From 28175d86c7f8f78a57b8a2a5d46cdb869523d13c Mon Sep 17 00:00:00 2001 From: Cameron653 Date: Sat, 24 Sep 2016 14:12:43 -0400 Subject: [PATCH] Late September Sync (#579) * Elevators aren't bottomless voids! * Updates changelog * Sombrero Code * Fixes #2365 * Adds changelog * Sleeper is evil. * no message * Changelog * Stops observers from leaving prints on the ground. No more spooking the mortals, ghosts. * Allows autotraitor in secret to start with 0 players * Adds changelog * Makes diona slightly less slow * Adds changelog * Bowling Shirts * Updates changelog * Adds a missing description * Flat Cap Changes and Hair Bow * Fixed Error * Adds an in-hand * Lower Torso cannot be amputated * Smoke works, adds changelog * Updates changelog * Makes Unathi Voidsuits Less Fat * Medical related fixes * Fuzzy Cuffs * Tube Top * Made Icons for Security Suit Less Gaunt * Revert "Medical related fixes" This reverts commit d7c59520e626dc2cebd6ec8dbd89d6ca94ad661f. * Just the fix to random med item now * Adds organ fixing * Fixes Evening Glove Coloring * HAZMAT Suits * Changes Unathi sprite slightly * Tweaks skirt pathing * Corrects changelog * Adds changelog * Construction Voidsuits * makes people bleed real good * adderino changeling * Biohazard Voidsuit * Revert "Revert "Adds hub passwordu"" * Explosive implants should no longer gib on limbs. * Adds space penguins and space geese. * Revert "Revert "Revert "Adds hub passwordu""" * Makes flash rounds respect eye protection * Water > Fire * There's plenty lying around, I think * Naming inconsistencies fixed The short naming of central command has been really inconsistent across the game's files. This has always annoyed the shit out of me. CentComm and Centcomm and Centcom are now all CentCom, specifically with that capitalization. Why one M instead of two M's? Because Comm with two 'M's = Communications. Hence, Telecomms, NOT Telecoms. Telecoms is incorrect. CentCom was also chosen because CentCom with one M and this casing is most found throughout the game's files. Speaking of Telecomms, I corrected one instance in the game where it's Telecom. Like I said, this is not correct. There was only one inconsistency. Likewise, Nanotrasen has been changed to NanoTrasen. Nanotrasen only appears 20 times, where NanoTrasen appears 62. NanoTrasen is clearly the preferred, correct naming. * Almost forgot plural of Telecomm * Finalizes work, adds designs to research. * Press Vest * Removes Mags/Shells, Adds Recorder and Flashlight * Fixes spans. * Raises the number of players needed to start Ninja * Still needs to fix internal bleeding * Allows Wirer To Attach to Toolbelts * Fixes #393 * Tweaks FBP temperature * Corrects Changelog * Fixes some Advanced Egun oversights * Embiggens the laser carbine and the lasercannon. * Messenger Bags * Health analyzers detect appendicitis * Custom Circuit Additions & Fixes Adds Med Scanner and Advanced Med Scanner circuits. Clock circuit is now functional. Five second delay will delay for five seconds and not one second. Renaming circuitry now respects ability to do so (e.g. being alive). Firing circuit can now be obtained by science normally. Examining inside assembly cases now requires adjacency. * More Additions You can now cancel inputting on a text or numberpad. Zero is now displayed properly on the UI and not be shown as null. The small and medium assemblies now have real sprites. Total health percentage for med scanners and advanced med scanners now reports a proper percentage and not 1 or 0. The constant memory chip now can be set by using it in hand, making it usable. The constant memory chip now accepts refs as data to store. To use, select 'ref' when using inhand, then hit it against the thing you want to store. * Allows Chemists to View Medical Records on their PDA * Refactors splinting * Refactors the forceMove() drop. Makes dropping a its proc instead, cleaning up forceMove() handling. * Replaces ORGAN_SPLINTED * Supportive suits now only loop through bad organs * Adds changelog * Lasercannon tweaks * Bloodloss tweak * Adds hawaii shirt Attachable to any uniform, works like suit jackets. * Changelog cause why not At this rate I'll forget how to do those otherwise * Adds randomized alohas Also some color matrix helpers from TG * Appendicitis doesn't cancel itself out. * Removes debug stuff * Radsuit Sprite Changes * Allows us to actually use the messenger bags * Fixes spelling mistake * Ported ventcrawling from vg. * Fixes changelog errors * Updates changelog * Tweaks vent crawling. The ability to ventcrawl is now checked by the /handle_ventcrawl() proc, making it possible to properly check before and after the do_after() call. Moves various checks into the base can_ventcrawl proc. Now lists the first object that prevents a mob from ventcrawling, making it easier to correct the exception list. Removes the issmall() check, instead checks if the crawling mob has the relevant verb. Fixes #14081. * Suit Storage Items * Adds in IB removal * More Circuit Things Adds Locomotion circuit, which makes the machine move in a given direction. Adds Signaler circuit, which can send and receive signals from a signaler. Adds a new tool, the Debugger, which lets one directly set data in a specific pin. It can also pulse activation pins. Adds ability to define custom cooldown times for each component. Smoke generator now has a 30 second cooldown. Cleans up some code somewhat. * Adds design for locomotion circuit. * Cleans up code * Even more sprites by Mechoid. Fixes abs to rel converter. * Black Messenger Bag * Powersink fix * Even More Sodding Circuits Adds new RNG circuit, to make random numbers each time. Adds new Concatenating circuit, so you can make lots of small strings into one big one. Adds new light and advanced light circuit. Basic just has a normal light that can be toggled. Advanced allows it to be any color using RGB, and a brightness between 0 and 6. New sprites for the debugger and wirer, by Mechoid. Hopefully finally fixes smoke generator from being unobtainable. * Adds basic circuit kit and spare circuit tools to Tech Storage. * Part the first * Changelog * Allows robots to be constructed with prosthetic limbs as well as borg limbs. * Map change * Secbelt can hold stun revolvers and eguns * Voidsuit Sprite Changes * Tweaks burst laser * Lasers, energy projectiles, and muzzle flashes now produce light. It's a bit wonky due to lighting only updating once every half-second, but it's very much functional, at least on my desktop. * Adds bridge bunnies * Slightly cleans up the occupation screen, adds uniform to locker * Map Changes * Adds Changelog * Fixes stuff * Allows jobbanning of cargo department jobs * Re-adds balance changes to heavy lasers. They got changed by accident when I did the laser light show. Also, adds changelogs for my last couple changes, because I'm an idiot and forgot them. * Fixed missing sprite * Dress Loadout Additions * I Can't Believe It's Not Circuits (it is) Fixes numberpad and letterpad pulsing. Debugger and Constant chip can now have null written to it. Adds new sound output, with two types so far. One being the 'beeper' type, which can do things like buzz, ping, beep, etc. The second type is a securitron speaker, which allows us to get closer to building a functioning Beepsky. * Adds EPv2 Circuit Adds a circuit that allows it to send and receive EPv2 messages, allowing for a more robust transmission of data that signalers cannot deliver. Bonus: Communicators can send text messages to custom machines using this. * Updates changelog * Fixes not being able to put things in medkits. * Technomancer Tweaks Cost for various spells and equipment adjusted greatly. In general, things are cheaper, and everything should now be in multiples of 25, so no points are wasted. The default jumpsuit for Technomancers is now heavily insulated, protecting them from tasers, batons, and perhaps unfortunate lightning strikes. Instability between 31 and 50 made less harsh. Wards made with a scepter of enhancement will break the cloak of anyone invisible that it can see. Fire aura buffed, increased rate of heating as well as temperature cap for both non-scepter and scepter effects. Reflect spell made more forgiving for the Technomancer, lasting longer before expiring. Projectile spells should be able to hit people more reliably. * Shotgun Reloading Tweak Adds ability to hit a shotgun or similar weapon with a container containing ammo, to load said ammo into the shotgun one at a time automatically, instead of having to play inventory tetris, as requested by some people. * Use sanitizeName for the guest pass terminal name input to prevent excessively long names. * Circuit UI and Assembly Tweaks Adds new drone assembly, which has stats between the medium and large assembly. Sprites by Mechoid. Assemblies now have a light UI when examined while opened, which displays what's inside, as well as how close to the cap for parts or complexity you are getting. Click the names of a component to open the wiring interface for that component. You can also rename each component from the UI. Bonus: Having multiple components of the same name will no longer appear as one component. Adds ability to rename the assembly, using the new UI. * Revert "Ported ventcrawling from vg." * Re-adds a nice, useful macro * Fixes #2431 * Tweaks Riot armor * Fixes a typo in the DNA Modifier * Ripped Jeans (And White Shorts) * Adds shanking * Adds changelog * Removes a stray world << * Ported ventcrawling from vg. * Tweaks vent crawling. The ability to ventcrawl is now checked by the /handle_ventcrawl() proc, making it possible to properly check before and after the do_after() call. Moves various checks into the base can_ventcrawl proc. Now lists the first object that prevents a mob from ventcrawling, making it easier to correct the exception list. Removes the issmall() check, instead checks if the crawling mob has the relevant verb. Fixes #14081. * Long, time-consuming not one-line fix * Makes cigs branded too Description of cig/cigbutt would reveal its brand for dastardly murdersolving revelations. * Adding a article * The door hacker now only pings the user * Removes implants from Deathsquad * Adds the ability to apply pressure to bleeding wounds * Shoes * EVA rigs should use their default sprites on Taj and Unathi * Fixing some errors * Update loadout_xeno.dm * Delete back_vr.dmi * Add files via upload --- code/ATMOSPHERICS/atmospherics.dm | 2 + .../binary_devices/binary_atmos_base.dm | 3 - .../components/binary_devices/pipeturbine.dm | 3 - .../trinary_devices/trinary_base.dm | 2 - code/ATMOSPHERICS/components/tvalve.dm | 2 - code/ATMOSPHERICS/components/valve.dm | 2 - code/ATMOSPHERICS/pipes.dm | 11 - code/__defines/damage_organs.dm | 5 +- code/_helpers/global_lists.dm | 2 +- code/_helpers/matrices.dm | 98 ++++ code/_helpers/mobs.dm | 6 +- code/_macros.dm | 3 + code/controllers/shuttle_controller.dm | 2 +- code/datums/ai_law_sets.dm | 4 +- code/datums/locations/nyx.dm | 8 +- code/datums/locations/vir.dm | 2 +- code/game/antagonist/outsider/deathsquad.dm | 2 +- code/game/antagonist/outsider/mercenary.dm | 1 + code/game/antagonist/outsider/wizard.dm | 1 + code/game/area/Space Station 13 areas.dm | 58 +- code/game/atoms.dm | 25 +- code/game/atoms_movable.dm | 34 +- code/game/dna/dna_modifier.dm | 2 +- code/game/gamemodes/cult/runes.dm | 15 + code/game/gamemodes/newobjective.dm | 2 +- code/game/gamemodes/ninja/ninja.dm | 4 +- code/game/gamemodes/technomancer/clothing.dm | 11 +- .../devices/disposable_teleporter.dm | 2 +- .../technomancer/devices/shield_armor.dm | 2 +- .../technomancer/devices/tesla_armor.dm | 2 +- code/game/gamemodes/technomancer/equipment.dm | 20 +- .../gamemodes/technomancer/instability.dm | 12 +- .../technomancer/spells/abjuration.dm | 2 +- .../technomancer/spells/apportation.dm | 2 +- .../technomancer/spells/audible_deception.dm | 2 +- .../technomancer/spells/aura/biomed_aura.dm | 2 +- .../technomancer/spells/aura/fire_aura.dm | 10 +- .../technomancer/spells/aura/frost_aura.dm | 2 +- .../technomancer/spells/aura/shock_aura.dm | 2 +- .../gamemodes/technomancer/spells/blink.dm | 2 +- .../gamemodes/technomancer/spells/control.dm | 2 +- .../technomancer/spells/energy_siphon.dm | 2 +- .../technomancer/spells/flame_tongue.dm | 2 +- .../gamemodes/technomancer/spells/illusion.dm | 2 +- .../technomancer/spells/insert/corona.dm | 2 +- .../technomancer/spells/insert/mend_organs.dm | 2 +- .../spells/insert/repel_missiles.dm | 2 +- .../technomancer/spells/instability_tap.dm | 2 +- .../technomancer/spells/mark_recall.dm | 4 +- .../technomancer/spells/oxygenate.dm | 2 +- .../technomancer/spells/phase_shift.dm | 2 +- .../technomancer/spells/projectile/beam.dm | 2 +- .../spells/projectile/force_missile.dm | 2 +- .../spells/projectile/overload.dm | 2 +- .../spells/projectile/projectile.dm | 3 +- .../gamemodes/technomancer/spells/radiance.dm | 2 +- .../gamemodes/technomancer/spells/reflect.dm | 8 +- .../gamemodes/technomancer/spells/shield.dm | 2 +- .../technomancer/spells/spawner/darkness.dm | 2 +- .../technomancer/spells/spawner/pulsar.dm | 2 +- .../spells/summon/summon_creature.dm | 2 +- .../technomancer/spells/summon/summon_ward.dm | 9 +- .../technomancer/spells/targeting_matrix.dm | 2 +- .../technomancer/spells/warp_strike.dm | 2 +- .../gamemodes/technomancer/technomancer.dm | 4 +- code/game/jobs/access.dm | 5 + code/game/jobs/job/assistant.dm | 1 + code/game/jobs/job/captain.dm | 38 +- code/game/jobs/job/civilian.dm | 4 + code/game/jobs/job/engineering.dm | 3 + code/game/jobs/job/job.dm | 1 + code/game/jobs/job/medical.dm | 6 + code/game/jobs/job/science.dm | 3 + code/game/jobs/job/security.dm | 4 + code/game/jobs/jobs.dm | 4 +- code/game/machinery/adv_med.dm | 4 +- code/game/machinery/camera/tracking.dm | 2 +- .../game/machinery/computer/communications.dm | 6 +- code/game/machinery/computer/guestpass.dm | 2 +- .../computer3/computers/communications.dm | 10 +- code/game/machinery/computer3/file.dm | 4 +- code/game/machinery/computer3/lapvend.dm | 4 +- code/game/machinery/frame.dm | 101 +++- code/game/machinery/suit_storage_unit.dm | 17 +- code/game/machinery/telecomms/presets.dm | 14 +- .../effects/decals/posters/tgposters.dm | 4 +- code/game/objects/items/devices/PDA/cart.dm | 1 + code/game/objects/items/devices/hacktool.dm | 2 +- code/game/objects/items/devices/powersink.dm | 2 +- code/game/objects/items/devices/scanners.dm | 15 +- code/game/objects/items/stacks/medical.dm | 26 +- .../objects/items/weapons/cigs_lighters.dm | 3 + .../objects/items/weapons/storage/backpack.dm | 59 +++ .../objects/items/weapons/storage/belt.dm | 3 + .../objects/items/weapons/storage/fancy.dm | 12 + .../objects/items/weapons/storage/toolbox.dm | 4 +- .../structures/crates_lockers/closets.dm | 3 + .../crates_lockers/closets/wardrobe.dm | 4 + .../structures/crates_lockers/crates.dm | 2 +- code/global.dm | 2 +- code/modules/admin/topic.dm | 37 +- code/modules/admin/verbs/pray.dm | 4 +- .../preference_setup/general/04_equipment.dm | 2 +- .../loadout/loadout_accessories.dm | 14 +- .../preference_setup/loadout/loadout_shoes.dm | 20 + .../loadout/loadout_uniform.dm | 18 +- .../preference_setup/loadout/loadout_xeno.dm | 2 +- .../preference_setup/occupation/occupation.dm | 2 +- code/modules/clothing/head/misc.dm | 2 +- code/modules/clothing/shoes/jobs.dm | 9 +- code/modules/clothing/shoes/miscellaneous.dm | 12 + .../clothing/spacesuits/rig/suits/station.dm | 15 +- .../modules/clothing/spacesuits/spacesuits.dm | 28 +- .../clothing/spacesuits/void/station.dm | 14 +- code/modules/clothing/suits/armor.dm | 7 +- code/modules/clothing/suits/miscellaneous.dm | 11 + code/modules/clothing/suits/utility.dm | 1 - .../clothing/under/accessories/clothing.dm | 18 +- code/modules/clothing/under/miscellaneous.dm | 7 + code/modules/clothing/under/pants.dm | 25 + code/modules/clothing/under/shorts.dm | 4 + code/modules/economy/TradeDestinations.dm | 2 +- code/modules/examine/descriptions/devices.dm | 2 +- .../modules/examine/descriptions/telecomms.dm | 2 +- code/modules/games/cards.dm | 2 +- .../integrated_electronics/_defines.dm | 387 ++++++++++++++ .../integrated_electronics/arithmetic.dm | 183 +++++++ .../integrated_electronics/assemblies.dm | 168 ++++++ .../integrated_electronics/converters.dm | 133 +++++ .../integrated_electronics/coordinate.dm | 75 +++ .../integrated_electronics/data_transfer.dm | 79 +++ .../integrated_electronics/input_output.dm | 494 ++++++++++++++++++ code/modules/integrated_electronics/logic.dm | 172 ++++++ .../integrated_electronics/manipulation.dm | 158 ++++++ code/modules/integrated_electronics/memory.dm | 101 ++++ code/modules/integrated_electronics/time.dm | 144 +++++ code/modules/integrated_electronics/tools.dm | 227 ++++++++ code/modules/mob/holder.dm | 5 + code/modules/mob/inventory.dm | 21 +- code/modules/mob/living/bot/cleanbot.dm | 10 +- code/modules/mob/living/bot/ed209bot.dm | 2 +- code/modules/mob/living/bot/farmbot.dm | 12 + code/modules/mob/living/bot/floorbot.dm | 2 +- code/modules/mob/living/bot/medbot.dm | 23 + code/modules/mob/living/bot/secbot.dm | 24 +- .../mob/living/carbon/carbon_defense.dm | 77 ++- .../mob/living/carbon/human/examine.dm | 23 +- code/modules/mob/living/carbon/human/human.dm | 2 +- .../living/carbon/human/human_attackhand.dm | 37 +- .../mob/living/carbon/human/human_defense.dm | 29 +- .../mob/living/carbon/human/human_defines.dm | 3 +- .../mob/living/carbon/human/human_movement.dm | 4 +- .../mob/living/carbon/human/human_organs.dm | 4 +- code/modules/mob/living/carbon/human/life.dm | 6 +- .../mob/living/carbon/human/stripping.dm | 12 +- .../mob/living/carbon/human/update_icons.dm | 3 + .../mob/living/carbon/metroid/metroid.dm | 5 - code/modules/mob/living/living.dm | 122 +---- code/modules/mob/living/living_powers.dm | 10 - code/modules/mob/living/silicon/ai/ai.dm | 2 +- code/modules/mob/living/silicon/ai/icons.dm | 2 +- .../modules/mob/living/silicon/robot/robot.dm | 2 + .../living/simple_animal/friendly/penguin.dm | 19 + .../mob/living/simple_animal/hostile/goose.dm | 34 ++ code/modules/mob/mob.dm | 2 +- code/modules/mob/mob_grab.dm | 6 +- code/modules/mob/new_player/new_player.dm | 2 +- .../mob/new_player/preferences_setup.dm | 2 +- code/modules/multiz/pipes.dm | 3 - code/modules/organs/blood.dm | 14 +- code/modules/organs/internal/appendix.dm | 2 +- code/modules/organs/organ.dm | 1 - code/modules/organs/organ_external.dm | 65 ++- code/modules/paperwork/adminpaper.dm | 2 +- code/modules/paperwork/faxmachine.dm | 6 +- code/modules/projectiles/effects.dm | 95 +++- code/modules/projectiles/gun.dm | 70 +++ code/modules/projectiles/guns/energy/laser.dm | 7 +- .../projectiles/guns/energy/nuclear.dm | 17 +- code/modules/projectiles/guns/projectile.dm | 18 + code/modules/projectiles/projectile.dm | 4 + .../modules/projectiles/projectile/animate.dm | 3 + code/modules/projectiles/projectile/beams.dm | 24 +- code/modules/projectiles/projectile/energy.dm | 23 +- .../modules/projectiles/projectile/special.dm | 13 + .../Chemistry-Reagents-Core.dm | 4 +- code/modules/research/designs.dm | 421 +++++++++++++++ .../scripting/Implementations/Telecomms.dm | 2 +- code/modules/shuttles/shuttle_ferry.dm | 8 +- code/modules/surgery/bones.dm | 1 - code/modules/vehicles/vehicle.dm | 2 + code/modules/ventcrawl/ventcrawl.dm | 185 +++++++ .../ventcrawl/ventcrawl_atmospherics.dm | 86 +++ code/modules/ventcrawl/ventcrawl_multiz.dm | 24 + code/modules/ventcrawl/ventcrawl_verb.dm | 7 + code/unit_tests/zas_tests.dm | 6 +- html/changelog.html | 44 ++ html/changelogs/HarpyEagle-Bleeding.yml | 6 + html/changelogs/Yoshax-Shanking.yml | 36 ++ html/changelogs/zuhayr-vent.yml | 5 + icons/mob/animal.dmi | Bin 203944 -> 206319 bytes icons/mob/back.dmi | Bin 81937 -> 85974 bytes icons/mob/back_vr.dmi | Bin 427 -> 424 bytes icons/mob/items/lefthand_shoes.dmi | Bin 1993 -> 2121 bytes icons/mob/items/righthand_shoes.dmi | Bin 2082 -> 2203 bytes icons/obj/electronic_assemblies.dmi | Bin 0 -> 23986 bytes icons/obj/gun.dmi | Bin 58990 -> 58691 bytes icons/obj/storage.dmi | Bin 69984 -> 72096 bytes maps/RandomZLevels/stationCollision.dm | 205 ++++++++ sound/machines/ventcrawl.ogg | Bin 0 -> 40591 bytes vorestation.dme | 18 + 211 files changed, 4812 insertions(+), 518 deletions(-) create mode 100644 code/modules/integrated_electronics/_defines.dm create mode 100644 code/modules/integrated_electronics/arithmetic.dm create mode 100644 code/modules/integrated_electronics/assemblies.dm create mode 100644 code/modules/integrated_electronics/converters.dm create mode 100644 code/modules/integrated_electronics/coordinate.dm create mode 100644 code/modules/integrated_electronics/data_transfer.dm create mode 100644 code/modules/integrated_electronics/input_output.dm create mode 100644 code/modules/integrated_electronics/logic.dm create mode 100644 code/modules/integrated_electronics/manipulation.dm create mode 100644 code/modules/integrated_electronics/memory.dm create mode 100644 code/modules/integrated_electronics/time.dm create mode 100644 code/modules/integrated_electronics/tools.dm create mode 100644 code/modules/mob/living/simple_animal/friendly/penguin.dm create mode 100644 code/modules/mob/living/simple_animal/hostile/goose.dm create mode 100644 code/modules/ventcrawl/ventcrawl.dm create mode 100644 code/modules/ventcrawl/ventcrawl_atmospherics.dm create mode 100644 code/modules/ventcrawl/ventcrawl_multiz.dm create mode 100644 code/modules/ventcrawl/ventcrawl_verb.dm create mode 100644 html/changelogs/HarpyEagle-Bleeding.yml create mode 100644 html/changelogs/Yoshax-Shanking.yml create mode 100644 html/changelogs/zuhayr-vent.yml create mode 100644 icons/obj/electronic_assemblies.dmi create mode 100644 maps/RandomZLevels/stationCollision.dm create mode 100644 sound/machines/ventcrawl.ogg diff --git a/code/ATMOSPHERICS/atmospherics.dm b/code/ATMOSPHERICS/atmospherics.dm index 7acf465b3e..b5d4df814e 100644 --- a/code/ATMOSPHERICS/atmospherics.dm +++ b/code/ATMOSPHERICS/atmospherics.dm @@ -29,6 +29,8 @@ Pipelines + Other Objects -> Pipe network var/pipe_color var/global/datum/pipe_icon_manager/icon_manager + var/obj/machinery/atmospherics/node1 + var/obj/machinery/atmospherics/node2 /obj/machinery/atmospherics/New() if(!icon_manager) diff --git a/code/ATMOSPHERICS/components/binary_devices/binary_atmos_base.dm b/code/ATMOSPHERICS/components/binary_devices/binary_atmos_base.dm index 37985034b1..2ccfe0f2e8 100644 --- a/code/ATMOSPHERICS/components/binary_devices/binary_atmos_base.dm +++ b/code/ATMOSPHERICS/components/binary_devices/binary_atmos_base.dm @@ -6,9 +6,6 @@ obj/machinery/atmospherics/binary var/datum/gas_mixture/air1 var/datum/gas_mixture/air2 - var/obj/machinery/atmospherics/node1 - var/obj/machinery/atmospherics/node2 - var/datum/pipe_network/network1 var/datum/pipe_network/network2 diff --git a/code/ATMOSPHERICS/components/binary_devices/pipeturbine.dm b/code/ATMOSPHERICS/components/binary_devices/pipeturbine.dm index 0eb342479d..5768def1ec 100644 --- a/code/ATMOSPHERICS/components/binary_devices/pipeturbine.dm +++ b/code/ATMOSPHERICS/components/binary_devices/pipeturbine.dm @@ -17,9 +17,6 @@ var/dP = 0 - var/obj/machinery/atmospherics/node1 - var/obj/machinery/atmospherics/node2 - var/datum/pipe_network/network1 var/datum/pipe_network/network2 diff --git a/code/ATMOSPHERICS/components/trinary_devices/trinary_base.dm b/code/ATMOSPHERICS/components/trinary_devices/trinary_base.dm index 3f5d66f262..fa066d978f 100644 --- a/code/ATMOSPHERICS/components/trinary_devices/trinary_base.dm +++ b/code/ATMOSPHERICS/components/trinary_devices/trinary_base.dm @@ -7,8 +7,6 @@ obj/machinery/atmospherics/trinary var/datum/gas_mixture/air2 var/datum/gas_mixture/air3 - var/obj/machinery/atmospherics/node1 - var/obj/machinery/atmospherics/node2 var/obj/machinery/atmospherics/node3 var/datum/pipe_network/network1 diff --git a/code/ATMOSPHERICS/components/tvalve.dm b/code/ATMOSPHERICS/components/tvalve.dm index 963a4f5009..f93970a93f 100644 --- a/code/ATMOSPHERICS/components/tvalve.dm +++ b/code/ATMOSPHERICS/components/tvalve.dm @@ -12,8 +12,6 @@ var/state = 0 // 0 = go straight, 1 = go to side // like a trinary component, node1 is input, node2 is side output, node3 is straight output - var/obj/machinery/atmospherics/node1 - var/obj/machinery/atmospherics/node2 var/obj/machinery/atmospherics/node3 var/datum/pipe_network/network_node1 diff --git a/code/ATMOSPHERICS/components/valve.dm b/code/ATMOSPHERICS/components/valve.dm index 6e43afd78e..8969523db4 100644 --- a/code/ATMOSPHERICS/components/valve.dm +++ b/code/ATMOSPHERICS/components/valve.dm @@ -12,8 +12,6 @@ var/open = 0 var/openDuringInit = 0 - var/obj/machinery/atmospherics/node1 - var/obj/machinery/atmospherics/node2 var/datum/pipe_network/network_node1 var/datum/pipe_network/network_node2 diff --git a/code/ATMOSPHERICS/pipes.dm b/code/ATMOSPHERICS/pipes.dm index c445988c53..105aaa8c8b 100644 --- a/code/ATMOSPHERICS/pipes.dm +++ b/code/ATMOSPHERICS/pipes.dm @@ -153,9 +153,6 @@ dir = SOUTH initialize_directions = SOUTH|NORTH - var/obj/machinery/atmospherics/node1 - var/obj/machinery/atmospherics/node2 - var/minimum_temperature_difference = 300 var/thermal_conductivity = 0 //WALL_HEAT_TRANSFER_COEFFICIENT No @@ -427,8 +424,6 @@ dir = SOUTH initialize_directions = EAST|NORTH|WEST - var/obj/machinery/atmospherics/node1 - var/obj/machinery/atmospherics/node2 var/obj/machinery/atmospherics/node3 level = 1 @@ -687,8 +682,6 @@ dir = SOUTH initialize_directions = NORTH|SOUTH|EAST|WEST - var/obj/machinery/atmospherics/node1 - var/obj/machinery/atmospherics/node2 var/obj/machinery/atmospherics/node3 var/obj/machinery/atmospherics/node4 @@ -1074,8 +1067,6 @@ initialize_directions = SOUTH density = 1 - var/obj/machinery/atmospherics/node1 - /obj/machinery/atmospherics/pipe/tank/New() icon_state = "air" initialize_directions = dir @@ -1238,8 +1229,6 @@ var/build_killswitch = 1 - var/obj/machinery/atmospherics/node1 - /obj/machinery/atmospherics/pipe/vent/New() initialize_directions = dir ..() diff --git a/code/__defines/damage_organs.dm b/code/__defines/damage_organs.dm index 124be53452..3c0e190427 100644 --- a/code/__defines/damage_organs.dm +++ b/code/__defines/damage_organs.dm @@ -35,9 +35,8 @@ #define ORGAN_BLEEDING (1<<1) #define ORGAN_BROKEN (1<<2) #define ORGAN_DESTROYED (1<<3) -#define ORGAN_SPLINTED (1<<4) -#define ORGAN_DEAD (1<<5) -#define ORGAN_MUTATED (1<<6) +#define ORGAN_DEAD (1<<4) +#define ORGAN_MUTATED (1<<5) #define DROPLIMB_EDGE 0 #define DROPLIMB_BLUNT 1 diff --git a/code/_helpers/global_lists.dm b/code/_helpers/global_lists.dm index 9a90a3676b..044b2264ce 100644 --- a/code/_helpers/global_lists.dm +++ b/code/_helpers/global_lists.dm @@ -55,7 +55,7 @@ var/global/list/skin_styles_female_list = list() //unused var/datum/category_collection/underwear/global_underwear = new() //Backpacks -var/global/list/backbaglist = list("Nothing", "Backpack", "Satchel", "Satchel Alt") +var/global/list/backbaglist = list("Nothing", "Backpack", "Satchel", "Satchel Alt", "Messenger Bag") var/global/list/pdachoicelist = list("Default", "Slim", "Old") var/global/list/exclude_jobs = list(/datum/job/ai,/datum/job/cyborg) diff --git a/code/_helpers/matrices.dm b/code/_helpers/matrices.dm index abb0366382..129e0d41b7 100644 --- a/code/_helpers/matrices.dm +++ b/code/_helpers/matrices.dm @@ -15,3 +15,101 @@ animate(src, transform = m120, time = speed, loops) animate(transform = m240, time = speed) animate(transform = m360, time = speed) + +//The X pixel offset of this matrix +/matrix/proc/get_x_shift() + . = c + +//The Y pixel offset of this matrix +/matrix/proc/get_y_shift() + . = f +// Color matrices: + +//Luma coefficients suggested for HDTVs. If you change these, make sure they add up to 1. +#define LUMR 0.2126 +#define LUMG 0.7152 +#define LUMB 0.0722 + +//Still need color matrix addition, negation, and multiplication. + +//Returns an identity color matrix which does nothing +/proc/color_identity() + return list(1,0,0, 0,1,0, 0,0,1) + +//Moves all colors angle degrees around the color wheel while maintaining intensity of the color and not affecting whites +//TODO: Need a version that only affects one color (ie shift red to blue but leave greens and blues alone) +/proc/color_rotation(angle) + if(angle == 0) + return color_identity() + angle = Clamp(angle, -180, 180) + var/cos = cos(angle) + var/sin = sin(angle) + + var/constA = 0.143 + var/constB = 0.140 + var/constC = -0.283 + return list( + LUMR + cos * (1-LUMR) + sin * -LUMR, LUMR + cos * -LUMR + sin * constA, LUMR + cos * -LUMR + sin * -(1-LUMR), + LUMG + cos * -LUMG + sin * -LUMG, LUMG + cos * (1-LUMG) + sin * constB, LUMG + cos * -LUMG + sin * LUMG, + LUMB + cos * -LUMB + sin * (1-LUMB), LUMB + cos * -LUMB + sin * constC, LUMB + cos * (1-LUMB) + sin * LUMB + ) + +//Makes everything brighter or darker without regard to existing color or brightness +/proc/color_brightness(power) + power = Clamp(power, -255, 255) + power = power/255 + + return list(1,0,0, 0,1,0, 0,0,1, power,power,power) + +/var/list/delta_index = list( + 0, 0.01, 0.02, 0.04, 0.05, 0.06, 0.07, 0.08, 0.1, 0.11, + 0.12, 0.14, 0.15, 0.16, 0.17, 0.18, 0.20, 0.21, 0.22, 0.24, + 0.25, 0.27, 0.28, 0.30, 0.32, 0.34, 0.36, 0.38, 0.40, 0.42, + 0.44, 0.46, 0.48, 0.5, 0.53, 0.56, 0.59, 0.62, 0.65, 0.68, + 0.71, 0.74, 0.77, 0.80, 0.83, 0.86, 0.89, 0.92, 0.95, 0.98, + 1.0, 1.06, 1.12, 1.18, 1.24, 1.30, 1.36, 1.42, 1.48, 1.54, + 1.60, 1.66, 1.72, 1.78, 1.84, 1.90, 1.96, 2.0, 2.12, 2.25, + 2.37, 2.50, 2.62, 2.75, 2.87, 3.0, 3.2, 3.4, 3.6, 3.8, + 4.0, 4.3, 4.7, 4.9, 5.0, 5.5, 6.0, 6.5, 6.8, 7.0, + 7.3, 7.5, 7.8, 8.0, 8.4, 8.7, 9.0, 9.4, 9.6, 9.8, + 10.0) + +//Exxagerates or removes brightness +/proc/color_contrast(value) + value = Clamp(value, -100, 100) + if(value == 0) + return color_identity() + + var/x = 0 + if (value < 0) + x = 127 + value / 100 * 127; + else + x = value % 1 + if(x == 0) + x = delta_index[value] + else + x = delta_index[value] * (1-x) + delta_index[value+1] * x//use linear interpolation for more granularity. + x = x * 127 + 127 + + var/mult = x / 127 + var/add = 0.5 * (127-x) / 255 + return list(mult,0,0, 0,mult,0, 0,0,mult, add,add,add) + +//Exxagerates or removes colors +/proc/color_saturation(value as num) + if(value == 0) + return color_identity() + value = Clamp(value, -100, 100) + if(value > 0) + value *= 3 + var/x = 1 + value / 100 + var/inv = 1 - x + var/R = LUMR * inv + var/G = LUMG * inv + var/B = LUMB * inv + + return list(R + x,R,R, G,G + x,G, B,B,B + x) + +#undef LUMR +#undef LUMG +#undef LUMB \ No newline at end of file diff --git a/code/_helpers/mobs.dm b/code/_helpers/mobs.dm index 8a1df2059b..70456bee77 100644 --- a/code/_helpers/mobs.dm +++ b/code/_helpers/mobs.dm @@ -158,7 +158,7 @@ Proc for attack log creation, because really why not else return pick("chest", "groin") -/proc/do_mob(mob/user , mob/target, time = 30, uninterruptible = 0, progress = 1) +/proc/do_mob(mob/user , mob/target, time = 30, target_zone = 0, uninterruptible = 0, progress = 1) if(!user || !target) return 0 var/user_loc = user.loc @@ -194,6 +194,10 @@ Proc for attack log creation, because really why not . = 0 break + if(target_zone && user.zone_sel.selecting != target_zone) + . = 0 + break + if (progbar) qdel(progbar) diff --git a/code/_macros.dm b/code/_macros.dm index 06376205d1..5b94c872cb 100644 --- a/code/_macros.dm +++ b/code/_macros.dm @@ -1,4 +1,5 @@ #define Clamp(x, y, z) (x <= y ? y : (x >= z ? z : x)) + #define CLAMP01(x) (Clamp(x, 0, 1)) #define get_turf(A) get_step(A,0) @@ -42,3 +43,5 @@ #define isxeno(A) istype(A, /mob/living/simple_animal/xeno) #define RANDOM_BLOOD_TYPE pick(4;"O-", 36;"O+", 3;"A-", 28;"A+", 1;"B-", 20;"B+", 1;"AB-", 5;"AB+") + +#define to_chat(target, message) target << message diff --git a/code/controllers/shuttle_controller.dm b/code/controllers/shuttle_controller.dm index 35ef52ff81..7a0deaf799 100644 --- a/code/controllers/shuttle_controller.dm +++ b/code/controllers/shuttle_controller.dm @@ -209,7 +209,7 @@ var/global/datum/shuttle_controller/shuttle_controller shuttle.docking_controller_tag = "centcom_shuttle" shuttle.dock_target_station = "centcom_shuttle_dock_airlock" shuttle.dock_target_offsite = "centcom_shuttle_bay" - shuttles["Centcom"] = shuttle + shuttles["CentCom"] = shuttle process_shuttles += shuttle shuttle = new() diff --git a/code/datums/ai_law_sets.dm b/code/datums/ai_law_sets.dm index 50e05948d5..e2c5161d6d 100644 --- a/code/datums/ai_law_sets.dm +++ b/code/datums/ai_law_sets.dm @@ -10,7 +10,7 @@ add_inherent_law("You must protect your own existence as long as such does not conflict with the First or Second Law.") ..() -/******************** Nanotrasen/Malf ********************/ +/******************** NanoTrasen/Malf ********************/ /datum/ai_laws/nanotrasen name = "NT Default" selectable = 1 @@ -30,7 +30,7 @@ set_zeroth_law(config.law_zero) ..() -/************* Nanotrasen Aggressive *************/ +/************* NanoTrasen Aggressive *************/ /datum/ai_laws/nanotrasen_aggressive name = "NT Aggressive" selectable = 1 diff --git a/code/datums/locations/nyx.dm b/code/datums/locations/nyx.dm index 35d79243b2..33df619660 100644 --- a/code/datums/locations/nyx.dm +++ b/code/datums/locations/nyx.dm @@ -43,15 +43,15 @@ /datum/locations/exodus name = "NSS Exodus" - desc = "A highly profitable research, mining, and supply dock for Nanotrasen that serves as one of their many facilities in exploiting the \ + desc = "A highly profitable research, mining, and supply dock for NanoTrasen that serves as one of their many facilities in exploiting the \ wonders of phoron. It is currently orbiting around Erebus and maintains close contact with the NAS Crescent. The station itself has been \ - a target for a large number of Mercenaries and other companies wishing to steal Nanotrasen's secrets." + a target for a large number of Mercenaries and other companies wishing to steal NanoTrasen's secrets." /datum/locations/crescent name = "NAS Crescent" - desc = "The main hub for Nanotrasen in the Nyx system and is commonly referred to it by their workers as central command or \"Centcomm\". \ + desc = "The main hub for NanoTrasen in the Nyx system and is commonly referred to it by their workers as central command or \"CentCom\". \ The Crescent refines and stores much of the products that stations (such as the Exodus) bring in. It is also a large refueling and supply \ - station of phoron and tritium in the Nyx system due to Nanotrasen being able to outsell almost any other company." + station of phoron and tritium in the Nyx system due to NanoTrasen being able to outsell almost any other company." /datum/locations/emerald_habitation name = "Emerald Habitation" diff --git a/code/datums/locations/vir.dm b/code/datums/locations/vir.dm index f750fc4c85..377ecc9b03 100644 --- a/code/datums/locations/vir.dm +++ b/code/datums/locations/vir.dm @@ -49,7 +49,7 @@ /datum/locations/northern_star //Inception joke here name = "Northern Star" - desc = "The Northern Star is an asteroid colony owned and operated by Nanotrasen, among many other asteroid installations. \ + desc = "The Northern Star is an asteroid colony owned and operated by NanoTrasen, among many other asteroid installations. \ Originally conceived as 'just another pitstop' for weary asteroid miners, it has grown to become a significant installation in the Kara subsystem." /datum/locations/northern_star/New(var/creator) diff --git a/code/game/antagonist/outsider/deathsquad.dm b/code/game/antagonist/outsider/deathsquad.dm index 1234bdb1f6..c7e1d01094 100644 --- a/code/game/antagonist/outsider/deathsquad.dm +++ b/code/game/antagonist/outsider/deathsquad.dm @@ -49,7 +49,7 @@ var/datum/antagonist/deathsquad/deathsquad player.equip_to_slot_or_del(new /obj/item/weapon/gun/energy/pulse_rifle(player), slot_r_hand) player.equip_to_slot_or_del(new /obj/item/weapon/rig/ert/assetprotection(player), slot_back) player.equip_to_slot_or_del(new /obj/item/weapon/melee/energy/sword(player), slot_s_store) - player.implant_loyalty() +// player.implant_loyalty() var/obj/item/weapon/card/id/id = create_id("Asset Protection", player) if(id) diff --git a/code/game/antagonist/outsider/mercenary.dm b/code/game/antagonist/outsider/mercenary.dm index c27d510d8b..f4d92e4261 100644 --- a/code/game/antagonist/outsider/mercenary.dm +++ b/code/game/antagonist/outsider/mercenary.dm @@ -41,6 +41,7 @@ var/datum/antagonist/mercenary/mercs if(player.backbag == 2) player.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(player), slot_back) if(player.backbag == 3) player.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel/norm(player), slot_back) if(player.backbag == 4) player.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(player), slot_back) + if(player.backbag == 5) player.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/messenger(player), slot_back) player.equip_to_slot_or_del(new /obj/item/weapon/storage/box/engineer(player.back), slot_in_backpack) player.equip_to_slot_or_del(new /obj/item/weapon/reagent_containers/pill/cyanide(player), slot_in_backpack) player.mind.tcrystals = DEFAULT_TELECRYSTAL_AMOUNT diff --git a/code/game/antagonist/outsider/wizard.dm b/code/game/antagonist/outsider/wizard.dm index 14e5f90063..b88af1b1b9 100644 --- a/code/game/antagonist/outsider/wizard.dm +++ b/code/game/antagonist/outsider/wizard.dm @@ -83,6 +83,7 @@ var/datum/antagonist/wizard/wizards if(wizard_mob.backbag == 2) wizard_mob.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(wizard_mob), slot_back) if(wizard_mob.backbag == 3) wizard_mob.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel/norm(wizard_mob), slot_back) if(wizard_mob.backbag == 4) wizard_mob.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(wizard_mob), slot_back) + if(wizard_mob.backbag == 5) wizard_mob.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(wizard_mob), slot_back) wizard_mob.equip_to_slot_or_del(new /obj/item/weapon/storage/box(wizard_mob), slot_in_backpack) wizard_mob.equip_to_slot_or_del(new /obj/item/weapon/teleportation_scroll(wizard_mob), slot_r_store) wizard_mob.equip_to_slot_or_del(new /obj/item/weapon/spellbook(wizard_mob), slot_r_hand) diff --git a/code/game/area/Space Station 13 areas.dm b/code/game/area/Space Station 13 areas.dm index 7b97481965..0a75438480 100755 --- a/code/game/area/Space Station 13 areas.dm +++ b/code/game/area/Space Station 13 areas.dm @@ -166,7 +166,7 @@ area/space/atmosalert() icon_state = "shuttle2" /area/shuttle/escape/centcom - name = "\improper Emergency Shuttle Centcom" + name = "\improper Emergency Shuttle CentCom" icon_state = "shuttle" /area/shuttle/escape/transit // the area to pass through for 3 minute transit @@ -282,6 +282,7 @@ area/space/atmosalert() /area/shuttle/cryo/station icon_state = "shuttle2" + base_turf = /turf/simulated/mineral/floor/ignore_mapgen /area/shuttle/cryo/centcom icon_state = "shuttle" @@ -290,9 +291,10 @@ area/space/atmosalert() icon_state = "shuttle" /area/shuttle/mining - name = "\improper Mining Shuttle" + name = "\improper Mining Elevator" music = "music/escape.ogg" lighting_use_dynamic = 0 + base_turf = /turf/simulated/mineral/floor/ignore_mapgen /area/shuttle/mining/station icon_state = "shuttle2" @@ -302,7 +304,7 @@ area/space/atmosalert() /area/shuttle/transport1/centcom icon_state = "shuttle" - name = "\improper Transport Shuttle Centcom" + name = "\improper Transport Shuttle CentCom" /area/shuttle/transport1/station icon_state = "shuttle" @@ -344,7 +346,7 @@ area/space/atmosalert() icon_state = "shuttlered2" /area/shuttle/administration/centcom - name = "\improper Administration Shuttle Centcom" + name = "\improper Administration Shuttle CentCom" icon_state = "shuttlered" /area/shuttle/administration/station @@ -352,7 +354,7 @@ area/space/atmosalert() icon_state = "shuttlered2" /area/shuttle/trade/centcom - name = "\improper Trade Shuttle Centcom" + name = "\improper Trade Shuttle CentCom" icon_state = "shuttlered" /area/shuttle/trade/station @@ -388,9 +390,10 @@ area/space/atmosalert() // === Trying to remove these areas: /area/shuttle/research - name = "\improper Research Shuttle" + name = "\improper Research Elevator" music = "music/escape.ogg" lighting_use_dynamic = 0 + base_turf = /turf/simulated/mineral/floor/ignore_mapgen /area/shuttle/research/station icon_state = "shuttle2" @@ -412,34 +415,34 @@ area/space/atmosalert() // CENTCOM /area/centcom - name = "\improper Centcom" + name = "\improper CentCom" icon_state = "centcom" requires_power = 0 lighting_use_dynamic = 0 /area/centcom/control - name = "\improper Centcom Control" + name = "\improper CentCom Control" /area/centcom/evac - name = "\improper Centcom Emergency Shuttle" + name = "\improper CentCom Emergency Shuttle" /area/centcom/suppy - name = "\improper Centcom Supply Shuttle" + name = "\improper CentCom Supply Shuttle" /area/centcom/ferry - name = "\improper Centcom Transport Shuttle" + name = "\improper CentCom Transport Shuttle" /area/centcom/shuttle - name = "\improper Centcom Administration Shuttle" + name = "\improper CentCom Administration Shuttle" /area/centcom/test - name = "\improper Centcom Testing Facility" + name = "\improper CentCom Testing Facility" /area/centcom/living - name = "\improper Centcom Living Quarters" + name = "\improper CentCom Living Quarters" /area/centcom/specops - name = "\improper Centcom Special Ops" + name = "\improper CentCom Special Ops" /area/centcom/creed name = "Creed's Office" @@ -455,15 +458,15 @@ area/space/atmosalert() name = "\improper Tram Station" /area/centcom/security - name = "\improper Centcom Security" + name = "\improper CentCom Security" icon_state = "centcom_security" /area/centcom/medical - name = "\improper Centcom Medical" + name = "\improper CentCom Medical" icon_state = "centcom_medical" /area/centcom/command - name = "\improper Centcom Command" //Central Command Command totally isn't RAS Syndrome in action. + name = "\improper CentCom Command" //Central Command Command totally isn't RAS Syndrome in action. icon_state = "centcom_command" /area/centcom/main_hall @@ -471,15 +474,15 @@ area/space/atmosalert() icon_state = "centcom_hallway1" /area/centcom/bar - name = "\improper Centcom Bar" + name = "\improper CentCom Bar" icon_state = "centcom_crew" /area/centcom/restaurant - name = "\improper Centcom Restaurant" + name = "\improper CentCom Restaurant" icon_state = "centcom_crew" /area/centcom/bathroom - name = "\improper Centcom Bathroom" + name = "\improper CentCom Bathroom" icon_state = "centcom_crew" //SYNDICATES @@ -2319,6 +2322,7 @@ area/space/atmosalert() name = "\improper Construction Site Shuttle" icon_state = "yellow" lighting_use_dynamic = 0 + base_turf = /turf/simulated/mineral/floor/ignore_mapgen /area/shuttle/constructionsite/station name = "\improper Construction Site Shuttle" @@ -2527,20 +2531,20 @@ area/space/atmosalert() ambience = list('sound/ambience/ambisin2.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/ambigen10.ogg') /area/tcommsat/entrance - name = "\improper Telecoms Teleporter" + name = "\improper Telecomms Teleporter" icon_state = "tcomsatentrance" /area/tcommsat/chamber - name = "\improper Telecoms Central Compartment" + name = "\improper Telecomms Central Compartment" icon_state = "tcomsatcham" /area/tcomsat - name = "\improper Telecoms Satellite" + name = "\improper Telecomms Satellite" icon_state = "tcomsatlob" ambience = list('sound/ambience/ambisin2.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/ambigen10.ogg') /area/tcomfoyer - name = "\improper Telecoms Foyer" + name = "\improper Telecomms Foyer" icon_state = "tcomsatentrance" ambience = list('sound/ambience/ambisin2.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/ambigen10.ogg') @@ -2555,7 +2559,7 @@ area/space/atmosalert() ambience = list('sound/ambience/ambisin2.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/ambigen10.ogg') /area/tcommsat/computer - name = "\improper Telecoms Control Room" + name = "\improper Telecomms Control Room" icon_state = "tcomsatcomp" /area/tcommsat/lounge @@ -2632,7 +2636,7 @@ area/space/atmosalert() requires_power = 0 /area/awaymission/spacebattle/cruiser - name = "\improper Nanotrasen Cruiser" + name = "\improper NanoTrasen Cruiser" /area/awaymission/spacebattle/syndicate1 name = "\improper Syndicate Assault Ship 1" diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 33f0635015..474b2d3b25 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -463,11 +463,11 @@ its easier to just keep the beam vertical. //spawn(0) //if(I) //It's possible that it could be deleted in the meantime. var/obj/O = I - O.show_message( message, 1, blind_message, 2) + O.show_message(message, 1, blind_message, 2) else if(ismob(I)) var/mob/M = I if(M.see_invisible >= invisibility) // Cannot view the invisible - M.show_message( message, 1, blind_message, 2) + M.show_message(message, 1, blind_message, 2) else if (blind_message) M.show_message(blind_message, 2) @@ -488,7 +488,24 @@ its easier to just keep the beam vertical. spawn(0) if(I) //It's possible that it could be deleted in the meantime. var/obj/O = I - O.show_message( message, 2, deaf_message, 1) + O.show_message(message, 2, deaf_message, 1) else if(ismob(I)) var/mob/M = I - M.show_message( message, 2, deaf_message, 1) + M.show_message(message, 2, deaf_message, 1) + +/atom/movable/proc/dropInto(var/atom/destination) + while(istype(destination)) + var/atom/drop_destination = destination.onDropInto(src) + if(!istype(drop_destination) || drop_destination == destination) + return forceMove(destination) + destination = drop_destination + return forceMove(null) + +/atom/proc/onDropInto(var/atom/movable/AM) + return // If onDropInto returns null, then dropInto will forceMove AM into us. + +/atom/movable/onDropInto(var/atom/movable/AM) + return loc // If onDropInto returns something, then dropInto will attempt to drop AM there. + +/atom/proc/InsertedContents() + return contents diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index e45be4bb6a..d164485f38 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -63,13 +63,35 @@ return /atom/movable/proc/forceMove(atom/destination) + if(loc == destination) + return 0 + var/is_origin_turf = isturf(loc) + var/is_destination_turf = isturf(destination) + // It is a new area if: + // Both the origin and destination are turfs with different areas. + // When either origin or destination is a turf and the other is not. + var/is_new_area = (is_origin_turf ^ is_destination_turf) || (is_origin_turf && is_destination_turf && loc.loc != destination.loc) + + var/atom/origin = loc + loc = destination + + if(origin) + origin.Exited(src, destination) + if(is_origin_turf) + for(var/atom/movable/AM in origin) + AM.Uncrossed(src) + if(is_new_area && is_origin_turf) + origin.loc.Exited(src, destination) + if(destination) - if(loc) - loc.Exited(src) - loc = destination - loc.Entered(src) - return 1 - return 0 + destination.Entered(src, origin) + if(is_destination_turf) // If we're entering a turf, cross all movable atoms + for(var/atom/movable/AM in loc) + if(AM != src) + AM.Crossed(src) + if(is_new_area && is_destination_turf) + destination.loc.Entered(src, origin) + return 1 //called when src is thrown into hit_atom /atom/movable/proc/throw_impact(atom/hit_atom, var/speed) diff --git a/code/game/dna/dna_modifier.dm b/code/game/dna/dna_modifier.dm index 56719fbce6..87971dd033 100644 --- a/code/game/dna/dna_modifier.dm +++ b/code/game/dna/dna_modifier.dm @@ -215,7 +215,7 @@ /obj/machinery/computer/scan_consolenew name = "DNA Modifier Access Console" - desc = "Scand DNA." + desc = "Scan DNA." icon = 'icons/obj/computer.dmi' icon_keyboard = "med_key" icon_screen = "dna" diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm index 91d802c8bf..8425105020 100644 --- a/code/game/gamemodes/cult/runes.dm +++ b/code/game/gamemodes/cult/runes.dm @@ -273,6 +273,21 @@ var/list/sacrificed = list() for (,drain>0,drain-=5) sleep(2) user.heal_organ_damage(5, 0) + if(ishuman(user)) + var/mob/living/carbon/human/H = user + for(var/obj/item/organ/I in H.internal_organs) + if(I.damage > 0) + I.damage = max(I.damage - 5, 0) //Heals 5 damage per organ per use + if(I.damage <= 5 && I.organ_tag == O_EYES) + H.sdisabilities &= ~BLIND + for(var/obj/item/organ/E in H.bad_external_organs) + var/obj/item/organ/external/affected = E + if((affected.damage < affected.min_broken_damage * config.organ_health_multiplier) && (affected.status & ORGAN_BROKEN)) + affected.status &= ~ORGAN_BROKEN + for(var/datum/wound/W in affected.wounds) + if(istype(W, /datum/wound/internal_bleeding)) + affected.wounds -= W + affected.update_damages() return diff --git a/code/game/gamemodes/newobjective.dm b/code/game/gamemodes/newobjective.dm index e8ea12b84b..1d41289ea2 100644 --- a/code/game/gamemodes/newobjective.dm +++ b/code/game/gamemodes/newobjective.dm @@ -264,7 +264,7 @@ datum target = targeta job = joba weight = get_points(job) - explanation_text = "Frame [target.current.real_name], the [target.assigned_role] for a crime and make sure they are arrested and brought back to the Centcom station alive. We'll handle the rest from there." + explanation_text = "Frame [target.current.real_name], the [target.assigned_role] for a crime and make sure they are arrested and brought back to the CentCom station alive. We'll handle the rest from there." check_completion() if(!emergency_shuttle.returned()) diff --git a/code/game/gamemodes/ninja/ninja.dm b/code/game/gamemodes/ninja/ninja.dm index 9109d9297b..f17b693455 100644 --- a/code/game/gamemodes/ninja/ninja.dm +++ b/code/game/gamemodes/ninja/ninja.dm @@ -9,8 +9,8 @@ the omniscience of the AI and rival the most hardened weapons your station is capable of. Tread lightly and \ only hope this unknown assassin isn't here for you." config_tag = "ninja" - required_players = 1 - required_players_secret = 3 + required_players = 5 + required_players_secret = 5 required_enemies = 1 end_on_antag_death = 0 antag_tags = list(MODE_NINJA) \ No newline at end of file diff --git a/code/game/gamemodes/technomancer/clothing.dm b/code/game/gamemodes/technomancer/clothing.dm index ef243aa484..3c3c79d58e 100644 --- a/code/game/gamemodes/technomancer/clothing.dm +++ b/code/game/gamemodes/technomancer/clothing.dm @@ -9,27 +9,30 @@ /obj/item/clothing/under/technomancer name = "initiate's jumpsuit" - desc = "It's a blue colored jumpsuit. There appears to be light-weight armor padding underneath, providing some protection." + desc = "It's a blue colored jumpsuit. There appears to be light-weight armor padding underneath, providing some protection. \ + There is also a healthy amount of insulation underneath." icon_state = "initiate" armor = list(melee = 10, bullet = 5, laser = 5, energy = 0, bomb = 0, bio = 0, rad = 0) - siemens_coefficient = 0.9 + siemens_coefficient = 0.3 /obj/item/clothing/under/technomancer/apprentice name = "apprentice's jumpsuit" desc = "It's a blue colored jumpsuit with some silver markings. There appears to be light-weight armor padding \ - underneath, providing some protection." + underneath, providing some protection. There is also a healthy amount of insulation underneath." icon_state = "apprentice" /obj/item/clothing/under/technomancer/master name = "master's jumpsuit" desc = "It's a blue colored jumpsuit with some gold markings. There appears to be light-weight armor padding \ - underneath, providing some protection." + underneath, providing some protection. There is also a healthy amount of insulation underneath." icon_state = "technomancer" /obj/item/clothing/head/technomancer name = "initiate's hat" desc = "It's a somewhat silly looking blue pointed hat." icon_state = "initiate" + armor = list(melee = 10, bullet = 5, laser = 5, energy = 0, bomb = 0, bio = 0, rad = 0) + siemens_coefficient = 0.3 /obj/item/clothing/head/technomancer/apprentice name = "apprentice's hat" diff --git a/code/game/gamemodes/technomancer/devices/disposable_teleporter.dm b/code/game/gamemodes/technomancer/devices/disposable_teleporter.dm index 43f0f2737a..4ce5f8a16a 100644 --- a/code/game/gamemodes/technomancer/devices/disposable_teleporter.dm +++ b/code/game/gamemodes/technomancer/devices/disposable_teleporter.dm @@ -2,7 +2,7 @@ name = "Disposable Teleporter" desc = "An ultra-safe teleportation device that can directly teleport you to a number of locations at minimal risk, however \ it has a limited amount of charges." - cost = 100 + cost = 50 obj_path = /obj/item/weapon/disposable_teleporter /obj/item/weapon/disposable_teleporter diff --git a/code/game/gamemodes/technomancer/devices/shield_armor.dm b/code/game/gamemodes/technomancer/devices/shield_armor.dm index 7bcd52babe..3e4ddbce1f 100644 --- a/code/game/gamemodes/technomancer/devices/shield_armor.dm +++ b/code/game/gamemodes/technomancer/devices/shield_armor.dm @@ -6,7 +6,7 @@ of which your Core can provide. When you are struck by something, the shield will block 75% of the damage, deducting energy \ proportional to the amount of force that was inflicted. Armor penetration has no effect on the shield's ability to protect \ you from harm, however the shield will fail if the energy supply cannot meet demand." - cost = 300 + cost = 200 obj_path = /obj/item/clothing/suit/armor/shield /obj/item/clothing/suit/armor/shield diff --git a/code/game/gamemodes/technomancer/devices/tesla_armor.dm b/code/game/gamemodes/technomancer/devices/tesla_armor.dm index 1446afcba7..6b981aa8eb 100644 --- a/code/game/gamemodes/technomancer/devices/tesla_armor.dm +++ b/code/game/gamemodes/technomancer/devices/tesla_armor.dm @@ -4,7 +4,7 @@ the next attack you suffer, and strike the attacker with a strong bolt of lightning. This effect requires twenty seconds to \ recharge. If you are attacked while this is recharging, a weaker lightning bolt is sent out, however you won't be protected from \ the person beating you." - cost = 250 + cost = 150 obj_path = /obj/item/clothing/suit/armor/tesla /obj/item/clothing/suit/armor/tesla diff --git a/code/game/gamemodes/technomancer/equipment.dm b/code/game/gamemodes/technomancer/equipment.dm index 2e0fe3833a..4c94d2e7f0 100644 --- a/code/game/gamemodes/technomancer/equipment.dm +++ b/code/game/gamemodes/technomancer/equipment.dm @@ -11,7 +11,7 @@ desc = "A core optimized for passive regeneration, however at the cost of capacity. Has a capacity of 7,000 units of energy, and \ recharges at a rate of 70 units. Complex gravatics and force manipulation allows the wearer to also run slightly faster, and \ reduces incoming instability from functions by 10%." - cost = 150 + cost = 100 obj_path = /obj/item/weapon/technomancer_core/rapid /datum/technomancer/equipment/bulky_core @@ -20,7 +20,7 @@ purchase one or more energy-generating Functions as well if using this core. Has a capacity of 20,000 units of energy, \ and recharges at a rate of 25 units. The intense weight of the core unfortunately can cause the wear to move slightly slower, \ and the closeness of the capacitors causes a slight increase in incoming instability by 10%." - cost = 150 + cost = 100 obj_path = /obj/item/weapon/technomancer_core/bulky /datum/technomancer/equipment/unstable @@ -29,7 +29,7 @@ better as the user has more instability, which could prove dangerous to the inexperienced or unprepared. Has a capacity of 13,000 \ units of energy, and recharges at a rate of 35 units at no instability, and approximately 110 units when within the \ 'yellow zone' of instability. Incoming instability is also amplified by 30%, due to the nature of this core." - cost = 150 + cost = 100 obj_path = /obj/item/weapon/technomancer_core/unstable /datum/technomancer/equipment/recycling @@ -38,7 +38,7 @@ cores. The focus on efficency also makes instability less of an issue, as incoming instability from functions are reduced by \ 40%. The capacitor is also slightly better, holding 12,000 units of energy, however the reactor is slower to recharge, at a rate \ of 40 units." - cost = 150 + cost = 100 obj_path = /obj/item/weapon/technomancer_core/recycling /datum/technomancer/equipment/summoning @@ -47,13 +47,13 @@ entities from vast distances, and keeping them there. Wearers of this core can maintain up to 30 summons at once, and the energy \ demand for maintaining summons is severely reduced. This comes at the price of capcitors that can only hold 8,000 units of energy, \ a recharging rate of 35 energy, and no shielding from instability." - cost = 150 + cost = 100 obj_path = /obj/item/weapon/technomancer_core/summoner /datum/technomancer/equipment/hypo_belt name = "Hypo Belt" desc = "A medical belt designed to carry autoinjectors and other medical equipment. Comes with one of each hypo." - cost = 100 + cost = 50 obj_path = /obj/item/weapon/storage/belt/medical/technomancer /obj/item/weapon/storage/belt/medical/technomancer @@ -76,7 +76,7 @@ desc = "A belt with a literal pocket which opens to a localized pocket of 'Blue-Space', allowing for more storage. \ The nature of the pocket allows for storage of larger objects than what is typical for other belts, and in larger quanities. \ It will also help keep your pants on." - cost = 100 + cost = 50 obj_path = /obj/item/weapon/storage/belt/holding /obj/item/weapon/storage/belt/holding @@ -103,7 +103,7 @@ /datum/technomancer/equipment/omni_sight name = "Omnisight Scanner" desc = "A very rare scanner worn on the face, which allows the wearer to see nearly anything across walls." - cost = 400 + cost = 300 obj_path = /obj/item/clothing/glasses/omni /obj/item/clothing/glasses/omni @@ -122,7 +122,7 @@ name = "Medical HUD" desc = "A commonly available HUD for medical professionals, which displays how healthy an individual is. \ Recommended for support-based apprentices!" - cost = 30 + cost = 25 obj_path = /obj/item/clothing/glasses/thermal/plain/monocle /datum/technomancer/equipment/scepter @@ -130,7 +130,7 @@ desc = "A gem sometimes found in the depths of asteroids makes up the basis for this device. Energy is channeled into it from \ the Core and the user, causing many functions to be enhanced in various ways, so long as it is held in the off-hand. \ Be careful not to lose this!" - cost = 300 + cost = 200 obj_path = /obj/item/weapon/scepter /obj/item/weapon/scepter diff --git a/code/game/gamemodes/technomancer/instability.dm b/code/game/gamemodes/technomancer/instability.dm index 6be83aef7b..0de94cba7a 100644 --- a/code/game/gamemodes/technomancer/instability.dm +++ b/code/game/gamemodes/technomancer/instability.dm @@ -112,7 +112,7 @@ rng = rand(0,8) switch(rng) if(0) - apply_effect(instability * 0.5, IRRADIATE) + apply_effect(instability * 0.3, IRRADIATE) if(1) return // visible_message("\The [src] suddenly collapses!", @@ -120,21 +120,21 @@ // Weaken(instability * 0.1) if(2) if(can_feel_pain()) - apply_effect(instability * 0.5, AGONY) + apply_effect(instability * 0.3, AGONY) src << "You feel a sharp pain!" if(3) - apply_effect(instability * 0.5, EYE_BLUR) + apply_effect(instability * 0.3, EYE_BLUR) src << "Your eyes start to get cloudy!" if(4) electrocute_act(instability * 0.3, "unstable energies") if(5) - adjustFireLoss(instability * 0.2) //10 burn @ 50 instability + adjustFireLoss(instability * 0.15) //7.5 burn @ 50 instability src << "You feel your skin burn!" if(6) - adjustBruteLoss(instability * 0.2) //10 brute @ 50 instability + adjustBruteLoss(instability * 0.15) //7.5 brute @ 50 instability src << "You feel a sharp pain as an unseen force harms your body!" if(7) - adjustToxLoss(instability * 0.2) //10 tox @ 50 instability + adjustToxLoss(instability * 0.15) //7.5 tox @ 50 instability if(8) safe_blink(src, range = 6) src << "You're teleported against your will!" diff --git a/code/game/gamemodes/technomancer/spells/abjuration.dm b/code/game/gamemodes/technomancer/spells/abjuration.dm index 2422ef00bf..005f1561bf 100644 --- a/code/game/gamemodes/technomancer/spells/abjuration.dm +++ b/code/game/gamemodes/technomancer/spells/abjuration.dm @@ -2,7 +2,7 @@ name = "Abjuration" desc = "This ability attempts to send summoned or teleported entities or anomalies to the place from whence they came, or at least \ far away from the caster. Failing that, it may inhibit those entities in some form." - cost = 40 + cost = 25 obj_path = /obj/item/weapon/spell/abjuration category = UTILITY_SPELLS diff --git a/code/game/gamemodes/technomancer/spells/apportation.dm b/code/game/gamemodes/technomancer/spells/apportation.dm index 150559b9cd..9cc95b1e6e 100644 --- a/code/game/gamemodes/technomancer/spells/apportation.dm +++ b/code/game/gamemodes/technomancer/spells/apportation.dm @@ -2,7 +2,7 @@ name = "Apportation" desc = "This allows you to teleport objects into your hand, or to pull people towards you. If they're close enough, the function \ will grab them automatically." - cost = 50 + cost = 25 obj_path = /obj/item/weapon/spell/apportation category = UTILITY_SPELLS diff --git a/code/game/gamemodes/technomancer/spells/audible_deception.dm b/code/game/gamemodes/technomancer/spells/audible_deception.dm index 06930828af..970d983894 100644 --- a/code/game/gamemodes/technomancer/spells/audible_deception.dm +++ b/code/game/gamemodes/technomancer/spells/audible_deception.dm @@ -3,7 +3,7 @@ desc = "Allows you to create a specific sound at a location of your choosing." enhancement_desc = "An extremely loud sound that a large amount of energy and instability becomes available, which will \ deafen and stun all who are near the targeted tile, including yourself if unprotected." - cost = 150 + cost = 50 obj_path = /obj/item/weapon/spell/audible_deception ability_icon_state = "tech_audibledeception" category = UTILITY_SPELLS diff --git a/code/game/gamemodes/technomancer/spells/aura/biomed_aura.dm b/code/game/gamemodes/technomancer/spells/aura/biomed_aura.dm index 52cbdfbfdf..024002814e 100644 --- a/code/game/gamemodes/technomancer/spells/aura/biomed_aura.dm +++ b/code/game/gamemodes/technomancer/spells/aura/biomed_aura.dm @@ -1,7 +1,7 @@ /datum/technomancer/spell/biomed_aura name = "Restoration Aura" desc = "Heals you and your allies (or everyone, if you want) of trauma and burns slowly, as long as they remain within four meters." - cost = 150 + cost = 100 obj_path = /obj/item/weapon/spell/aura/biomed ability_icon_state = "tech_biomedaura" category = SUPPORT_SPELLS diff --git a/code/game/gamemodes/technomancer/spells/aura/fire_aura.dm b/code/game/gamemodes/technomancer/spells/aura/fire_aura.dm index 0c28f31577..5e1028192b 100644 --- a/code/game/gamemodes/technomancer/spells/aura/fire_aura.dm +++ b/code/game/gamemodes/technomancer/spells/aura/fire_aura.dm @@ -4,7 +4,7 @@ This does not affect you or your allies. It also causes a large amount of fire to erupt around you, however the main threat is \ still the heating up." enhancement_desc = "Increased heat generation, more fires, and higher temperature cap." - cost = 150 + cost = 100 obj_path = /obj/item/weapon/spell/aura/fire ability_icon_state = "tech_fireaura" category = OFFENSIVE_SPELLS @@ -21,13 +21,13 @@ qdel(src) var/list/nearby_things = range(4,owner) - var/temp_change = 25 - var/temp_cap = 500 + var/temp_change = 40 + var/temp_cap = 600 var/fire_power = 2 if(check_for_scepter()) - temp_change = 50 - temp_cap = 700 + temp_change = 80 + temp_cap = 1000 fire_power = 4 for(var/mob/living/carbon/human/H in nearby_things) if(is_ally(H)) diff --git a/code/game/gamemodes/technomancer/spells/aura/frost_aura.dm b/code/game/gamemodes/technomancer/spells/aura/frost_aura.dm index d5dd78b793..610702646d 100644 --- a/code/game/gamemodes/technomancer/spells/aura/frost_aura.dm +++ b/code/game/gamemodes/technomancer/spells/aura/frost_aura.dm @@ -3,7 +3,7 @@ desc = "Lowers the core body temperature of everyone around you (except for your friends), causing them to freeze to death if \ they stay within four meters of you." enhancement_desc = "The chill becomes lethal." - cost = 150 + cost = 100 obj_path = /obj/item/weapon/spell/aura/frost ability_icon_state = "tech_frostaura" category = DEFENSIVE_SPELLS // Scepter-less frost aura is nonlethal. diff --git a/code/game/gamemodes/technomancer/spells/aura/shock_aura.dm b/code/game/gamemodes/technomancer/spells/aura/shock_aura.dm index a9e50b2fa3..70ae416ec0 100644 --- a/code/game/gamemodes/technomancer/spells/aura/shock_aura.dm +++ b/code/game/gamemodes/technomancer/spells/aura/shock_aura.dm @@ -1,7 +1,7 @@ /datum/technomancer/spell/shock_aura name = "Electric Aura" desc = "Repeatively electrocutes enemies within four meters of you, as well as nearby electronics." - cost = 150 + cost = 100 obj_path = /obj/item/weapon/spell/aura/shock ability_icon_state = "tech_shockaura" category = OFFENSIVE_SPELLS diff --git a/code/game/gamemodes/technomancer/spells/blink.dm b/code/game/gamemodes/technomancer/spells/blink.dm index 9dae12e39e..19f6e84c83 100644 --- a/code/game/gamemodes/technomancer/spells/blink.dm +++ b/code/game/gamemodes/technomancer/spells/blink.dm @@ -3,7 +3,7 @@ desc = "Force the target to teleport a short distance away. This target could be anything from something lying on the ground, to someone trying to \ fight you, or even yourself. Using this on someone next to you makes their potential distance after teleportation greater." enhancement_desc = "Blink distance is increased greatly." - cost = 100 + cost = 50 obj_path = /obj/item/weapon/spell/blink category = UTILITY_SPELLS diff --git a/code/game/gamemodes/technomancer/spells/control.dm b/code/game/gamemodes/technomancer/spells/control.dm index b5eaad8f44..17fb821d35 100644 --- a/code/game/gamemodes/technomancer/spells/control.dm +++ b/code/game/gamemodes/technomancer/spells/control.dm @@ -5,7 +5,7 @@ targets. This function will have no effect on entities of higher intelligence, such as humans and similar alien species, as it's \ not true mind control, but merely pheromone synthesis for living animals, and electronic hacking for simple robots. The green web \ around the entity is merely a hologram used to allow the user to know if the creature is safe or not." - cost = 200 + cost = 100 obj_path = /obj/item/weapon/spell/control category = UTILITY_SPELLS diff --git a/code/game/gamemodes/technomancer/spells/energy_siphon.dm b/code/game/gamemodes/technomancer/spells/energy_siphon.dm index 0e8e23ffd8..ad379b2d3c 100644 --- a/code/game/gamemodes/technomancer/spells/energy_siphon.dm +++ b/code/game/gamemodes/technomancer/spells/energy_siphon.dm @@ -4,7 +4,7 @@ Every second, electricity is stolen until the link is broken by the target moving too far away, or having no more energy left. \ Can drain from powercells, microbatteries, and other Cores. The beam created by the siphoning is harmful to touch." enhancement_desc = "Rate of siphoning is doubled." - cost = 150 + cost = 100 obj_path = /obj/item/weapon/spell/energy_siphon ability_icon_state = "tech_energysiphon" category = UTILITY_SPELLS diff --git a/code/game/gamemodes/technomancer/spells/flame_tongue.dm b/code/game/gamemodes/technomancer/spells/flame_tongue.dm index 5afa25ae90..923cde0b9d 100644 --- a/code/game/gamemodes/technomancer/spells/flame_tongue.dm +++ b/code/game/gamemodes/technomancer/spells/flame_tongue.dm @@ -1,7 +1,7 @@ /datum/technomancer/spell/flame_tongue name = "Flame Tongue" desc = "Using a miniturized flamethrower in your gloves, you can emit a flame strong enough to melt both your enemies and walls." - cost = 100 + cost = 50 obj_path = /obj/item/weapon/spell/flame_tongue ability_icon_state = "tech_flametongue" category = OFFENSIVE_SPELLS diff --git a/code/game/gamemodes/technomancer/spells/illusion.dm b/code/game/gamemodes/technomancer/spells/illusion.dm index e450e4480f..9667df1db4 100644 --- a/code/game/gamemodes/technomancer/spells/illusion.dm +++ b/code/game/gamemodes/technomancer/spells/illusion.dm @@ -2,7 +2,7 @@ name = "Illusion" desc = "Allows you to create and control a holographic illusion, that can take the form of most object or entities." enhancement_desc = "Illusions will be made of hard light, allowing the interception of attacks, appearing more realistic." - cost = 100 + cost = 25 obj_path = /obj/item/weapon/spell/illusion ability_icon_state = "tech_illusion" category = UTILITY_SPELLS diff --git a/code/game/gamemodes/technomancer/spells/insert/corona.dm b/code/game/gamemodes/technomancer/spells/insert/corona.dm index bde3ee9984..a070108a68 100644 --- a/code/game/gamemodes/technomancer/spells/insert/corona.dm +++ b/code/game/gamemodes/technomancer/spells/insert/corona.dm @@ -2,7 +2,7 @@ name = "Corona" desc = "Causes the victim to glow very brightly, which while harmless in itself, makes it easier for them to be hit. The \ bright glow also makes it very difficult to be stealthy. The effect lasts for one minute." - cost = 100 + cost = 50 obj_path = /obj/item/weapon/spell/insert/corona ability_icon_state = "tech_corona" category = SUPPORT_SPELLS diff --git a/code/game/gamemodes/technomancer/spells/insert/mend_organs.dm b/code/game/gamemodes/technomancer/spells/insert/mend_organs.dm index e9450b9586..a43bb7611d 100644 --- a/code/game/gamemodes/technomancer/spells/insert/mend_organs.dm +++ b/code/game/gamemodes/technomancer/spells/insert/mend_organs.dm @@ -2,7 +2,7 @@ name = "Mend Organs" desc = "Heals the target's internal organs, both organic and robotic. Instability is split between the target \ and technomancer, if seperate." - cost = 75 + cost = 50 obj_path = /obj/item/weapon/spell/insert/mend_organs ability_icon_state = "tech_mendwounds" category = SUPPORT_SPELLS diff --git a/code/game/gamemodes/technomancer/spells/insert/repel_missiles.dm b/code/game/gamemodes/technomancer/spells/insert/repel_missiles.dm index 8fb549039f..a95afa0a1f 100644 --- a/code/game/gamemodes/technomancer/spells/insert/repel_missiles.dm +++ b/code/game/gamemodes/technomancer/spells/insert/repel_missiles.dm @@ -2,7 +2,7 @@ name = "Repel Missiles" desc = "Places a repulsion field around you, which attempts to deflect incoming bullets and lasers, making them 30% less likely \ to hit you. The field lasts for five minutes and can be granted to yourself or an ally." - cost = 60 + cost = 25 obj_path = /obj/item/weapon/spell/insert/repel_missiles ability_icon_state = "tech_repelmissiles" category = SUPPORT_SPELLS diff --git a/code/game/gamemodes/technomancer/spells/instability_tap.dm b/code/game/gamemodes/technomancer/spells/instability_tap.dm index ada2989444..8ad52f3b3f 100644 --- a/code/game/gamemodes/technomancer/spells/instability_tap.dm +++ b/code/game/gamemodes/technomancer/spells/instability_tap.dm @@ -2,7 +2,7 @@ name = "Instability Tap" desc = "Creates a large sum of energy, at the cost of a very large amount of instability afflicting you." enhancement_desc = "50% more energy gained, 20% less instability gained." - cost = 120 + cost = 100 obj_path = /obj/item/weapon/spell/instability_tap ability_icon_state = "tech_instabilitytap" category = UTILITY_SPELLS diff --git a/code/game/gamemodes/technomancer/spells/mark_recall.dm b/code/game/gamemodes/technomancer/spells/mark_recall.dm index 63e6d67fad..528b860094 100644 --- a/code/game/gamemodes/technomancer/spells/mark_recall.dm +++ b/code/game/gamemodes/technomancer/spells/mark_recall.dm @@ -3,7 +3,7 @@ desc = "This function places a specific 'mark' beacon under you, which is used by the Recall function as a destination. \ Note that using Mark again will move the destination instead of creating a second destination, and only one destination \ can exist, regardless of who casted Mark." - cost = 50 + cost = 25 obj_path = /obj/item/weapon/spell/mark ability_icon_state = "tech_mark" category = UTILITY_SPELLS @@ -50,7 +50,7 @@ desc = "This function teleports you to where you placed a mark using the Mark function. Without the Mark function, this \ function is useless. Note that teleporting takes three seconds. Being incapacitated while teleporting will cancel it." enhancement_desc = "Recall takes two seconds instead of three." - cost = 50 + cost = 25 obj_path = /obj/item/weapon/spell/recall ability_icon_state = "tech_recall" category = UTILITY_SPELLS diff --git a/code/game/gamemodes/technomancer/spells/oxygenate.dm b/code/game/gamemodes/technomancer/spells/oxygenate.dm index 3f9bb6f9e5..f1edc635c1 100644 --- a/code/game/gamemodes/technomancer/spells/oxygenate.dm +++ b/code/game/gamemodes/technomancer/spells/oxygenate.dm @@ -2,7 +2,7 @@ name = "Oxygenate" desc = "This function creates oxygen at a location of your chosing. If used on a humanoid entity, it heals oxygen deprivation. \ If casted on the envirnment, air (oxygen and nitrogen) is moved from a distant location to your target." - cost = 70 + cost = 50 obj_path = /obj/item/weapon/spell/oxygenate ability_icon_state = "oxygenate" category = SUPPORT_SPELLS diff --git a/code/game/gamemodes/technomancer/spells/phase_shift.dm b/code/game/gamemodes/technomancer/spells/phase_shift.dm index 20fb033872..a571d6789d 100644 --- a/code/game/gamemodes/technomancer/spells/phase_shift.dm +++ b/code/game/gamemodes/technomancer/spells/phase_shift.dm @@ -2,7 +2,7 @@ name = "Phase Shift" desc = "Hides you in the safest possible place, where no harm can come to you. Unfortunately you can only stay inside for a few moments before \ draining your powercell." - cost = 80 + cost = 50 obj_path = /obj/item/weapon/spell/phase_shift category = DEFENSIVE_SPELLS diff --git a/code/game/gamemodes/technomancer/spells/projectile/beam.dm b/code/game/gamemodes/technomancer/spells/projectile/beam.dm index 429a83dd9b..13d5fe934a 100644 --- a/code/game/gamemodes/technomancer/spells/projectile/beam.dm +++ b/code/game/gamemodes/technomancer/spells/projectile/beam.dm @@ -1,7 +1,7 @@ /datum/technomancer/spell/beam name = "Beam" desc = "Fires a laser at your target. Cheap, reliable, and a bit boring." - cost = 150 + cost = 100 ability_icon_state = "tech_beam" obj_path = /obj/item/weapon/spell/projectile/beam category = OFFENSIVE_SPELLS diff --git a/code/game/gamemodes/technomancer/spells/projectile/force_missile.dm b/code/game/gamemodes/technomancer/spells/projectile/force_missile.dm index dad3c88f45..ab295f58f3 100644 --- a/code/game/gamemodes/technomancer/spells/projectile/force_missile.dm +++ b/code/game/gamemodes/technomancer/spells/projectile/force_missile.dm @@ -2,7 +2,7 @@ name = "Force Missile" desc = "This fires a missile at your target. It's cheap to use, however the projectile itself moves and impacts in such a way \ that armor designed to protect from blunt force will mitigate this function as well." - cost = 100 + cost = 50 obj_path = /obj/item/weapon/spell/projectile/force_missile category = OFFENSIVE_SPELLS diff --git a/code/game/gamemodes/technomancer/spells/projectile/overload.dm b/code/game/gamemodes/technomancer/spells/projectile/overload.dm index e6f0c898e2..90bf50e7d6 100644 --- a/code/game/gamemodes/technomancer/spells/projectile/overload.dm +++ b/code/game/gamemodes/technomancer/spells/projectile/overload.dm @@ -2,7 +2,7 @@ name = "Overload" desc = "Fires a bolt of highly unstable energy, that does damaged equal to 1.5% of the technomancer's current reserve of energy. \ This energy pierces all known armor." - cost = 150 + cost = 100 obj_path = /obj/item/weapon/spell/projectile/overload category = OFFENSIVE_SPELLS diff --git a/code/game/gamemodes/technomancer/spells/projectile/projectile.dm b/code/game/gamemodes/technomancer/spells/projectile/projectile.dm index 69e1efc92f..ea2f0db4e3 100644 --- a/code/game/gamemodes/technomancer/spells/projectile/projectile.dm +++ b/code/game/gamemodes/technomancer/spells/projectile/projectile.dm @@ -10,10 +10,9 @@ var/fire_sound = null /obj/item/weapon/spell/projectile/on_ranged_cast(atom/hit_atom, mob/living/user) - var/turf/T = get_turf(hit_atom) if(set_up(hit_atom, user)) var/obj/item/projectile/new_projectile = new spell_projectile(get_turf(user)) - new_projectile.launch(T) + new_projectile.launch(hit_atom) if(fire_sound) playsound(get_turf(src), fire_sound, 75, 1) owner.adjust_instability(instability_per_shot) diff --git a/code/game/gamemodes/technomancer/spells/radiance.dm b/code/game/gamemodes/technomancer/spells/radiance.dm index 9d484ddc5c..7cd7694122 100644 --- a/code/game/gamemodes/technomancer/spells/radiance.dm +++ b/code/game/gamemodes/technomancer/spells/radiance.dm @@ -1,7 +1,7 @@ /datum/technomancer/spell/radiance name = "Radiance" desc = "Causes you to be very radiant, glowing brightly in visible light, thermal energy, and deadly ionizing radiation." - cost = 180 + cost = 100 obj_path = /obj/item/weapon/spell/radiance category = OFFENSIVE_SPELLS diff --git a/code/game/gamemodes/technomancer/spells/reflect.dm b/code/game/gamemodes/technomancer/spells/reflect.dm index 7a8fa0a4de..d841db2acc 100644 --- a/code/game/gamemodes/technomancer/spells/reflect.dm +++ b/code/game/gamemodes/technomancer/spells/reflect.dm @@ -1,7 +1,7 @@ /datum/technomancer/spell/reflect name = "Reflect" desc = "Emits a protective shield fron your hand in front of you, which will reflect one attack back at the attacker." - cost = 120 + cost = 100 obj_path = /obj/item/weapon/spell/reflect ability_icon_state = "tech_reflect" category = DEFENSIVE_SPELLS @@ -22,7 +22,7 @@ spark_system = PoolOrNew(/datum/effect/effect/system/spark_spread) spark_system.set_up(5, 0, src) owner << "Your shield will expire in 3 seconds!" - spawn(3 SECONDS) + spawn(5 SECONDS) if(src) owner << "Your shield expires!" qdel(src) @@ -67,7 +67,7 @@ if(!reflecting) reflecting = 1 - spawn(1 SECOND) //To ensure that most or all of a burst fire cycle is reflected. + spawn(2 SECONDS) //To ensure that most or all of a burst fire cycle is reflected. owner << "Your shield fades due being used up!" qdel(src) @@ -87,7 +87,7 @@ if(!reflecting) reflecting = 1 - spawn(1 SECOND) //To ensure that most or all of a burst fire cycle is reflected. + spawn(2 SECONDS) //To ensure that most or all of a burst fire cycle is reflected. owner << "Your shield fades due being used up!" qdel(src) return 1 diff --git a/code/game/gamemodes/technomancer/spells/shield.dm b/code/game/gamemodes/technomancer/spells/shield.dm index 330de0ff26..ac6910c478 100644 --- a/code/game/gamemodes/technomancer/spells/shield.dm +++ b/code/game/gamemodes/technomancer/spells/shield.dm @@ -2,7 +2,7 @@ name = "Shield" desc = "Emits a protective shield fron your hand in front of you, which will protect you from almost anything able to harm \ you, so long as you can power it." - cost = 120 + cost = 100 obj_path = /obj/item/weapon/spell/shield ability_icon_state = "tech_shield" category = DEFENSIVE_SPELLS diff --git a/code/game/gamemodes/technomancer/spells/spawner/darkness.dm b/code/game/gamemodes/technomancer/spells/spawner/darkness.dm index ac5e799d72..ecb18b3481 100644 --- a/code/game/gamemodes/technomancer/spells/spawner/darkness.dm +++ b/code/game/gamemodes/technomancer/spells/spawner/darkness.dm @@ -1,7 +1,7 @@ /datum/technomancer/spell/darkness name = "Darkness" desc = "Disrupts photons moving in a local area, causing darkness to shroud yourself or a position of your choosing." - cost = 30 + cost = 25 obj_path = /obj/item/weapon/spell/spawner/darkness category = UTILITY_SPELLS diff --git a/code/game/gamemodes/technomancer/spells/spawner/pulsar.dm b/code/game/gamemodes/technomancer/spells/spawner/pulsar.dm index a2c22b0f76..c1b016116a 100644 --- a/code/game/gamemodes/technomancer/spells/spawner/pulsar.dm +++ b/code/game/gamemodes/technomancer/spells/spawner/pulsar.dm @@ -1,7 +1,7 @@ /datum/technomancer/spell/pulsar name = "Pulsar" desc = "Emits electronic pulses to destroy, disable, or otherwise harm devices and machines. Be sure to not hit yourself with this." - cost = 150 + cost = 100 obj_path = /obj/item/weapon/spell/spawner/pulsar category = OFFENSIVE_SPELLS diff --git a/code/game/gamemodes/technomancer/spells/summon/summon_creature.dm b/code/game/gamemodes/technomancer/spells/summon/summon_creature.dm index 497a8422bd..053f449095 100644 --- a/code/game/gamemodes/technomancer/spells/summon/summon_creature.dm +++ b/code/game/gamemodes/technomancer/spells/summon/summon_creature.dm @@ -6,7 +6,7 @@ The creatures take a few moments to be teleported to the targeted tile. Note that the creatures summoned are \ not inherently loyal to the technomancer, and that the creatures will be hurt slightly from being teleported to you." enhancement_desc = "Summoned entities will never harm their summoner." - cost = 200 + cost = 100 obj_path = /obj/item/weapon/spell/summon/summon_creature category = UTILITY_SPELLS diff --git a/code/game/gamemodes/technomancer/spells/summon/summon_ward.dm b/code/game/gamemodes/technomancer/spells/summon/summon_ward.dm index 5323c5beda..e4154eddf2 100644 --- a/code/game/gamemodes/technomancer/spells/summon/summon_ward.dm +++ b/code/game/gamemodes/technomancer/spells/summon/summon_ward.dm @@ -3,7 +3,7 @@ desc = "Teleports a prefabricated 'ward' drone to the target location, which will alert you and your allies when it sees entities \ moving around it, or when it is attacked. They can see for up to five meters. Wards expire in six minutes." enhancement_desc = "Wards can detect invisibile entities, and are more specific in relaying information about what it sees." - cost = 100 + cost = 25 obj_path = /obj/item/weapon/spell/summon/summon_ward category = UTILITY_SPELLS @@ -84,6 +84,9 @@ if(L.alpha <= 127) continue // Too transparent, as a mercy to camo lings. + else + L.break_cloak() + // Warn the Technomancer when it sees a new mob. if(!(L in seen_mobs)) seen_mobs.Add(L) @@ -111,3 +114,7 @@ overlays.Cut() var/image/I = image('icons/mob/critter.dmi',"ward_truesight") overlays.Add(I) + +/mob/living/simple_animal/ward/invisible_detect + true_sight = 1 + see_invisible = SEE_INVISIBLE_LEVEL_TWO diff --git a/code/game/gamemodes/technomancer/spells/targeting_matrix.dm b/code/game/gamemodes/technomancer/spells/targeting_matrix.dm index aff00f0197..b227748aeb 100644 --- a/code/game/gamemodes/technomancer/spells/targeting_matrix.dm +++ b/code/game/gamemodes/technomancer/spells/targeting_matrix.dm @@ -2,7 +2,7 @@ name = "Targeting Matrix" desc = "Automatically targets and fires a ranged weapon or function at a non-friendly target near a targeted tile. \ Each target assisted attack costs some energy and instability." - cost = 150 + cost = 50 ability_icon_state = "tech_targetingmatrix" obj_path = /obj/item/weapon/spell/targeting_matrix category = UTILITY_SPELLS diff --git a/code/game/gamemodes/technomancer/spells/warp_strike.dm b/code/game/gamemodes/technomancer/spells/warp_strike.dm index a308066ae5..11b3ba032e 100644 --- a/code/game/gamemodes/technomancer/spells/warp_strike.dm +++ b/code/game/gamemodes/technomancer/spells/warp_strike.dm @@ -1,7 +1,7 @@ /datum/technomancer/spell/warp_strike name = "Warp Strike" desc = "Teleports you next to your target, and attacks them with whatever is in your off-hand, spell or object." - cost = 200 + cost = 100 obj_path = /obj/item/weapon/spell/warp_strike ability_icon_state = "tech_warpstrike" category = OFFENSIVE_SPELLS diff --git a/code/game/gamemodes/technomancer/technomancer.dm b/code/game/gamemodes/technomancer/technomancer.dm index a7131fb54c..cf37046d0f 100644 --- a/code/game/gamemodes/technomancer/technomancer.dm +++ b/code/game/gamemodes/technomancer/technomancer.dm @@ -7,8 +7,8 @@ their powers can be used for good or if their arrival foreshadows the destruction of the entire colony, or worse." config_tag = "technomancer" votable = 0 - required_players = 8 - required_players_secret = 10 + required_players = 5 + required_players_secret = 5 required_enemies = 1 end_on_antag_death = 0 antag_tags = list(MODE_TECHNOMANCER) \ No newline at end of file diff --git a/code/game/jobs/access.dm b/code/game/jobs/access.dm index c5d8f8f445..25acb8caa7 100644 --- a/code/game/jobs/access.dm +++ b/code/game/jobs/access.dm @@ -239,6 +239,11 @@ proc/get_all_job_icons() //For all existing HUD icons if(I.rank in job_icons) return I.rank + var/centcom = get_all_centcom_jobs() + if(I.assignment in centcom) //Return with the NT logo if it is a CentCom job + return "CentCom" + if(I.rank in centcom) + return "CentCom" else return diff --git a/code/game/jobs/job/assistant.dm b/code/game/jobs/job/assistant.dm index 5e2b40d952..cc0faede19 100644 --- a/code/game/jobs/job/assistant.dm +++ b/code/game/jobs/job/assistant.dm @@ -19,6 +19,7 @@ if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(H), slot_back) if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel/norm(H), slot_back) if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back) + if(5) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/messenger(H), slot_back) if(has_alt_title(H, alt_title,"Visitor")) //I doubt someone visiting the station would want to wear an ugly grey uniform H.equip_to_slot_or_del(new /obj/item/clothing/under/assistantformal(H), slot_w_uniform) else if(has_alt_title(H, alt_title,"Resident")) diff --git a/code/game/jobs/job/captain.dm b/code/game/jobs/job/captain.dm index c091a599c3..a98bfe4544 100644 --- a/code/game/jobs/job/captain.dm +++ b/code/game/jobs/job/captain.dm @@ -30,6 +30,7 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 1) if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/captain(H), slot_back) if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel/cap(H), slot_back) if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back) + if(5) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/messenger/com(H), slot_back) H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/captain(H), slot_w_uniform) if(H.age>49) // Since we can have something other than the default uniform at this @@ -109,4 +110,39 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 1) else H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/ids(H.back), slot_in_backpack) H.implant_loyalty() - return 1 \ No newline at end of file + return 1 + +/datum/job/secretary + title = "Command Secretary" + flag = BRIDGE + department = "Civilian" + head_position = 1 + department_flag = CIVILIAN + faction = "Station" + total_positions = 2 + spawn_positions = 2 + supervisors = "command staff" + selection_color = "#2F2F7F" + idtype = /obj/item/weapon/card/id/silver + alt_titles = list("Command Liaison", "Bridge Secretary") + minimal_player_age = 5 + economic_modifier = 7 + + access = list(access_heads) + minimal_access = list(access_heads) + +/datum/job/secretary/equip(var/mob/living/carbon/human/H) + if(!H) return 0 + H.equip_to_slot_or_del(new /obj/item/device/radio/headset/headset_com(H), slot_l_ear) + switch(H.backbag) + if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(H), slot_back) + if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel/norm(H), slot_back) + if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back) + H.equip_to_slot_or_del(new /obj/item/clothing/shoes/brown(H), slot_shoes) + H.equip_to_slot_or_del(new /obj/item/device/pda/heads/hop(H), slot_belt) + H.equip_to_slot_or_del(new /obj/item/weapon/storage/briefcase(H), slot_l_hand) + if(H.gender == FEMALE) + H.equip_to_slot_or_del(new /obj/item/clothing/under/suit_jacket/female/skirt(H), slot_w_uniform) + else + H.equip_to_slot_or_del(new /obj/item/clothing/under/suit_jacket/charcoal(H), slot_w_uniform) + return 1 \ No newline at end of file diff --git a/code/game/jobs/job/civilian.dm b/code/game/jobs/job/civilian.dm index b617c65da9..a8e4d3f3f6 100644 --- a/code/game/jobs/job/civilian.dm +++ b/code/game/jobs/job/civilian.dm @@ -21,6 +21,7 @@ if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(H), slot_back) if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel/norm(H), slot_back) if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back) + if(5) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/messenger(H), slot_back) H.equip_to_slot_or_del(new /obj/item/device/radio/headset/headset_service(H), slot_l_ear) H.equip_to_slot_or_del(new /obj/item/clothing/shoes/black(H), slot_shoes) H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/bartender(H), slot_w_uniform) @@ -86,6 +87,7 @@ if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/hydroponics(H), slot_back) if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel/hyd(H), slot_back) if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back) + if(5) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/messenger/hyd(H), slot_back) return 1 @@ -171,6 +173,7 @@ if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/industrial(H), slot_back) if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel/eng(H), slot_back) if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back) + if(5) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/messenger/engi(H), slot_back) H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/miner(H), slot_w_uniform) H.equip_to_slot_or_del(new /obj/item/device/pda/shaftminer(H), slot_belt) H.equip_to_slot_or_del(new /obj/item/clothing/shoes/black(H), slot_shoes) @@ -265,6 +268,7 @@ if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(H), slot_back) if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel/norm(H), slot_back) if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back) + if(5) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/messenger(H), slot_back) H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/internalaffairs(H), slot_w_uniform) H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/toggle/internalaffairs(H), slot_wear_suit) H.equip_to_slot_or_del(new /obj/item/clothing/shoes/brown(H), slot_shoes) diff --git a/code/game/jobs/job/engineering.dm b/code/game/jobs/job/engineering.dm index 53c642b816..227297ca05 100644 --- a/code/game/jobs/job/engineering.dm +++ b/code/game/jobs/job/engineering.dm @@ -35,6 +35,7 @@ if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/industrial(H), slot_back) if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel/eng(H), slot_back) if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back) + if(5) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/messenger/engi(H), slot_back) H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/chief_engineer(H), slot_w_uniform) H.equip_to_slot_or_del(new /obj/item/device/pda/heads/ce(H), slot_l_store) H.equip_to_slot_or_del(new /obj/item/clothing/shoes/workboots(H), slot_shoes) @@ -73,6 +74,7 @@ if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/industrial(H), slot_back) if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel/eng(H), slot_back) if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back) + if(5) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/messenger/engi(H), slot_back) H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/engineer(H), slot_w_uniform) H.equip_to_slot_or_del(new /obj/item/clothing/shoes/workboots(H), slot_shoes) H.equip_to_slot_or_del(new /obj/item/weapon/storage/belt/utility/full(H), slot_belt) @@ -111,6 +113,7 @@ if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(H), slot_back) if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel/norm(H), slot_back) if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back) + if(5) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/messenger/engi(H), slot_back) H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/atmospheric_technician(H), slot_w_uniform) H.equip_to_slot_or_del(new /obj/item/clothing/shoes/workboots(H), slot_shoes) H.equip_to_slot_or_del(new /obj/item/device/pda/atmos(H), slot_l_store) diff --git a/code/game/jobs/job/job.dm b/code/game/jobs/job/job.dm index 6c575bef00..6add65ce55 100644 --- a/code/game/jobs/job/job.dm +++ b/code/game/jobs/job/job.dm @@ -33,6 +33,7 @@ if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(H), slot_back) if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel/norm(H), slot_back) if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back) + if(5) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/messenger(H), slot_back) /datum/job/proc/equip_survival(var/mob/living/carbon/human/H) if(!H) return 0 diff --git a/code/game/jobs/job/medical.dm b/code/game/jobs/job/medical.dm index 69a94f0ade..0c2053f8d6 100644 --- a/code/game/jobs/job/medical.dm +++ b/code/game/jobs/job/medical.dm @@ -30,6 +30,7 @@ if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/medic(H), slot_back) if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel/med(H), slot_back) if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back) + if(5) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/messenger/med(H), slot_back) H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/chief_medical_officer(H), slot_w_uniform) H.equip_to_slot_or_del(new /obj/item/clothing/shoes/brown(H), slot_shoes) H.equip_to_slot_or_del(new /obj/item/device/pda/heads/cmo(H), slot_belt) @@ -63,6 +64,7 @@ if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/medic(H), slot_back) if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel/med(H), slot_back) if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back) + if(5) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/messenger/med(H), slot_back) if(has_alt_title(H, alt_title,"Emergency Physician")) H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/medical(H), slot_w_uniform) H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/toggle/fr_jacket(H), slot_wear_suit) @@ -78,6 +80,7 @@ if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/virology(H), slot_back) if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel/vir(H), slot_back) if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back) + if(5) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/messenger/viro(H), slot_back) else if(has_alt_title(H, alt_title,"Medical Doctor")) H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/medical(H), slot_w_uniform) H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/toggle/labcoat(H), slot_wear_suit) @@ -128,6 +131,7 @@ if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/chemistry(H), slot_back) if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel/chem(H), slot_back) if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back) + if(5) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/messenger/chem(H), slot_back) H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/toggle/labcoat/chemist(H), slot_wear_suit) return 1 @@ -185,6 +189,7 @@ if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(H), slot_back) if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel/norm(H), slot_back) if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back) + if(5) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/messenger(H), slot_back) if(has_alt_title(H, alt_title,"Psychiatrist")) H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/psych(H), slot_w_uniform) else if(has_alt_title(H, alt_title,"Psychologist")) @@ -221,6 +226,7 @@ if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/medic(H), slot_back) if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel/med(H), slot_back) if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back) + if(5) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/messenger/med(H), slot_back) if(has_alt_title(H, alt_title,"Emergency Medical Technician")) H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/medical/paramedic(H), slot_w_uniform) H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/toggle/fr_jacket(H), slot_wear_suit) diff --git a/code/game/jobs/job/science.dm b/code/game/jobs/job/science.dm index 3fb3de5c42..b13d623fd6 100644 --- a/code/game/jobs/job/science.dm +++ b/code/game/jobs/job/science.dm @@ -37,6 +37,7 @@ if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/toxins(H), slot_back) if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel/tox(H), slot_back) if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back) + if(5) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/messenger/tox(H), slot_back) H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/toggle/labcoat(H), slot_wear_suit) return 1 @@ -70,6 +71,7 @@ if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/toxins(H), slot_back) if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel/tox(H), slot_back) if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back) + if(5) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/messenger/tox(H), slot_back) H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/toggle/labcoat/science(H), slot_wear_suit) return 1 @@ -101,6 +103,7 @@ if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/toxins(H), slot_back) if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel/tox(H), slot_back) if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back) + if(5) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/messenger/tox(H), slot_back) H.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/toggle/labcoat/science(H), slot_wear_suit) return 1 diff --git a/code/game/jobs/job/security.dm b/code/game/jobs/job/security.dm index 071c1cbf1b..f151a5fb83 100644 --- a/code/game/jobs/job/security.dm +++ b/code/game/jobs/job/security.dm @@ -30,6 +30,7 @@ if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/security(H), slot_back) if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel/sec(H), slot_back) if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back) + if(5) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/messenger/sec(H), slot_back) H.equip_to_slot_or_del(new /obj/item/device/radio/headset/heads/hos(H), slot_l_ear) H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/head_of_security(H), slot_w_uniform) H.equip_to_slot_or_del(new /obj/item/clothing/shoes/jackboots(H), slot_shoes) @@ -70,6 +71,7 @@ if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/security(H), slot_back) if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel/sec(H), slot_back) if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back) + if(5) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/messenger/sec(H), slot_back) H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/warden(H), slot_w_uniform) H.equip_to_slot_or_del(new /obj/item/clothing/shoes/jackboots(H), slot_shoes) H.equip_to_slot_or_del(new /obj/item/device/pda/warden(H), slot_belt) @@ -108,6 +110,7 @@ if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(H), slot_back) if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel/norm(H), slot_back) if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back) + if(5) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/messenger(H), slot_back) H.equip_to_slot_or_del(new /obj/item/clothing/under/det(H), slot_w_uniform) H.equip_to_slot_or_del(new /obj/item/clothing/shoes/laceup(H), slot_shoes) H.equip_to_slot_or_del(new /obj/item/device/pda/detective(H), slot_belt) @@ -151,6 +154,7 @@ if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/security(H), slot_back) if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel/sec(H), slot_back) if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back) + if(5) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/messenger/sec(H), slot_back) H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/security(H), slot_w_uniform) H.equip_to_slot_or_del(new /obj/item/clothing/shoes/jackboots(H), slot_shoes) H.equip_to_slot_or_del(new /obj/item/device/pda/security(H), slot_belt) diff --git a/code/game/jobs/jobs.dm b/code/game/jobs/jobs.dm index 61324580ff..bf3b4ea8ff 100644 --- a/code/game/jobs/jobs.dm +++ b/code/game/jobs/jobs.dm @@ -44,6 +44,7 @@ var/const/CHAPLAIN =(1<<10) var/const/CLOWN =(1<<11) var/const/MIME =(1<<12) var/const/ASSISTANT =(1<<13) +var/const/BRIDGE =(1<<14) var/list/assistant_occupations = list( @@ -56,7 +57,8 @@ var/list/command_positions = list( "Head of Security", "Chief Engineer", "Research Director", - "Chief Medical Officer" + "Chief Medical Officer", + "Command Secretary" ) diff --git a/code/game/machinery/adv_med.dm b/code/game/machinery/adv_med.dm index 2e7224169f..5efd83bb92 100644 --- a/code/game/machinery/adv_med.dm +++ b/code/game/machinery/adv_med.dm @@ -329,7 +329,7 @@ organStatus["broken"] = E.broken_description if(E.status & ORGAN_ROBOT) organStatus["robotic"] = 1 - if(E.status & ORGAN_SPLINTED) + if(E.splinted) organStatus["splinted"] = 1 if(E.status & ORGAN_BLEEDING) organStatus["bleeding"] = 1 @@ -483,7 +483,7 @@ break if(istype(e, /obj/item/organ/external/chest) && occupant.is_lung_ruptured()) lung_ruptured = "Lung ruptured:" - if(e.status & ORGAN_SPLINTED) + if(e.splinted) splint = "Splinted:" if(e.status & ORGAN_BLEEDING) bled = "Bleeding:" diff --git a/code/game/machinery/camera/tracking.dm b/code/game/machinery/camera/tracking.dm index 739583ede8..cb57906e30 100644 --- a/code/game/machinery/camera/tracking.dm +++ b/code/game/machinery/camera/tracking.dm @@ -222,7 +222,7 @@ mob/living/proc/near_camera() /mob/living/proc/tracking_status() // Easy checks first. - // Don't detect mobs on Centcom. Since the wizard den is on Centcomm, we only need this. + // Don't detect mobs on CentCom. Since the wizard den is on CentCom, we only need this. var/obj/item/weapon/card/id/id = GetIdCard() if(id && id.prevent_tracking()) return TRACKING_TERMINATE diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm index a657d881a8..9ff98b84b4 100644 --- a/code/game/machinery/computer/communications.dm +++ b/code/game/machinery/computer/communications.dm @@ -173,7 +173,7 @@ src.updateDialog() // OMG CENTCOMM LETTERHEAD - if("MessageCentcomm") + if("MessageCentCom") if(src.authenticated==2) if(centcomm_message_cooldown) usr << "\red Arrays recycling. Please stand by." @@ -181,7 +181,7 @@ var/input = sanitize(input("Please choose a message to transmit to [boss_short] via quantum entanglement. Please be aware that this process is very expensive, and abuse will lead to... termination. Transmission does not guarantee a response. There is a 30 second delay before you may send another message, be clear, full and concise.", "To abort, send an empty message.", "")) if(!input || !(usr in view(1,src))) return - Centcomm_announce(input, usr) + CentCom_announce(input, usr) usr << "\blue Message transmitted." log_say("[key_name(usr)] has made an IA [boss_short] announcement: [input]") centcomm_message_cooldown = 1 @@ -295,7 +295,7 @@ if (src.authenticated==2) dat += "
\[ Make An Announcement \]" if(src.emagged == 0) - dat += "
\[ Send an emergency message to [boss_short] \]" + dat += "
\[ Send an emergency message to [boss_short] \]" else dat += "
\[ Send an emergency message to \[UNKNOWN\] \]" dat += "
\[ Restore Backup Routing Data \]" diff --git a/code/game/machinery/computer/guestpass.dm b/code/game/machinery/computer/guestpass.dm index 3fced68e65..b01b03f9b3 100644 --- a/code/game/machinery/computer/guestpass.dm +++ b/code/game/machinery/computer/guestpass.dm @@ -132,7 +132,7 @@ if (href_list["choice"]) switch(href_list["choice"]) if ("giv_name") - var/nam = sanitize(input("Person pass is issued to", "Name", giv_name) as text|null) + var/nam = sanitizeName(input("Person pass is issued to", "Name", giv_name) as text|null) if (nam) giv_name = nam if ("reason") diff --git a/code/game/machinery/computer3/computers/communications.dm b/code/game/machinery/computer3/computers/communications.dm index 8168a3f8da..cace79d378 100644 --- a/code/game/machinery/computer3/computers/communications.dm +++ b/code/game/machinery/computer3/computers/communications.dm @@ -22,8 +22,8 @@ /datum/file/program/communications - name = "Centcom communications relay" - desc = "Used to connect to Centcom." + name = "CentCom communications relay" + desc = "Used to connect to CentCom." active_state = "comm" req_access = list(access_heads) @@ -185,7 +185,7 @@ computer.updateDialog() // OMG CENTCOMM LETTERHEAD - if("MessageCentcomm" in href_list) + if("MessageCentCom" in href_list) if(!computer.radio.subspace) return if(authenticated==2) @@ -195,7 +195,7 @@ var/input = sanitize(input("Please choose a message to transmit to [boss_short] via quantum entanglement. Please be aware that this process is very expensive, and abuse will lead to... termination. Transmission does not guarantee a response.", "To abort, send an empty message.", "")) if(!input || !interactable()) return - Centcomm_announce(input, usr) + CentCom_announce(input, usr) usr << "Message transmitted." log_say("[key_name(usr)] has made a [boss_short] announcement: [input]") centcomm_message_cooldown = 1 @@ -288,7 +288,7 @@ if (authenticated==2) dat += "
\[ Make An Announcement \]" if(computer.emagged == 0) - dat += "
\[ Send an emergency message to [boss_short] \]" + dat += "
\[ Send an emergency message to [boss_short] \]" else dat += "
\[ Send an emergency message to \[UNKNOWN\] \]" dat += "
\[ Restore Backup Routing Data \]" diff --git a/code/game/machinery/computer3/file.dm b/code/game/machinery/computer3/file.dm index be4285b3e1..c425bcc0aa 100644 --- a/code/game/machinery/computer3/file.dm +++ b/code/game/machinery/computer3/file.dm @@ -62,13 +62,13 @@ return 1 /* - Centcom root authorization certificate + CentCom root authorization certificate Non-destructive, officially sanctioned. Has the same effect on computers as an emag. */ /datum/file/centcom_auth - name = "Centcom Root Access Token" + name = "CentCom Root Access Token" extension = "auth" volume = 100 copy() diff --git a/code/game/machinery/computer3/lapvend.dm b/code/game/machinery/computer3/lapvend.dm index 3800fb9440..e31dd57fa2 100644 --- a/code/game/machinery/computer3/lapvend.dm +++ b/code/game/machinery/computer3/lapvend.dm @@ -178,7 +178,7 @@ else usr << "\icon[src]Unable to access vendor account. Please record the machine ID and call [boss_short] Support." else - usr << "\icon[src]Unable to access vendor account. Please record the machine ID and call CentComm Support." + usr << "\icon[src]Unable to access vendor account. Please record the machine ID and call CentCom Support." else transfer_and_vend(CH, C) @@ -328,7 +328,7 @@ usr << "\icon[src]Unable to access vendor account. Please record the machine ID and call [boss_short] Support." return 0 else - usr << "\icon[src]Unable to access vendor account. Please record the machine ID and call CentComm Support." + usr << "\icon[src]Unable to access vendor account. Please record the machine ID and call CentCom Support." return 0 else transfer_and_reimburse(CH) diff --git a/code/game/machinery/frame.dm b/code/game/machinery/frame.dm index 3005996f0b..f553bfa9fe 100644 --- a/code/game/machinery/frame.dm +++ b/code/game/machinery/frame.dm @@ -447,6 +447,31 @@ state = 3 if(frame_type.frame_class == "machine") user << desc + else if(state == 3) + if(frame_type.frame_class == "machine") + for(var/I in req_components) + if(istype(P, I) && (req_components[I] > 0)) + playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1) + if(istype(P, /obj/item/stack/cable_coil)) + var/obj/item/stack/cable_coil/CP = P + if(CP.get_amount() > 1) + var/camt = min(CP.amount, req_components[I]) // amount of cable to take, idealy amount required, but limited by amount provided + var/obj/item/stack/cable_coil/CC = new /obj/item/stack/cable_coil(src) + CC.amount = camt + CC.update_icon() + CP.use(camt) + components += CC + req_components[I] -= camt + update_desc() + break + + user.drop_item() + P.forceMove(src) + components += P + req_components[I]-- + update_desc() + break + user << desc else if(istype(P, /obj/item/weapon/wirecutters)) if(state == 3) @@ -506,20 +531,7 @@ for(var/I in req_components) if(istype(P, I) && (req_components[I] > 0)) playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1) - if(istype(P, /obj/item/stack/cable_coil)) - var/obj/item/stack/cable_coil/CP = P - if(CP.get_amount() > 1) - var/camt = min(CP.amount, req_components[I]) // amount of cable to take, idealy amount required, but limited by amount provided - var/obj/item/stack/cable_coil/CC = new /obj/item/stack/cable_coil(src) - CC.amount = camt - CC.update_icon() - CP.use(camt) - components += CC - req_components[I] -= camt - update_desc() - break - - else if(istype(P, /obj/item/stack/material/glass/reinforced)) + if(istype(P, /obj/item/stack/material/glass/reinforced)) var/obj/item/stack/material/glass/reinforced/CP = P if(CP.get_amount() > 1) var/camt = min(CP.amount, req_components[I]) // amount of glass to take, idealy amount required, but limited by amount provided @@ -539,8 +551,65 @@ update_desc() break user << desc - if(P && P.loc != src && !istype(P, /obj/item/stack/cable_coil) && !istype(P, /obj/item/stack/material)) + if(P && P.loc != src && !istype(P, /obj/item/stack/material)) user << "You cannot add that component to the machine!" return - update_icon() \ No newline at end of file + update_icon() + +/obj/structure/frame/verb/rotate() + set name = "Rotate Frame Counter-Clockwise" + set category = "Object" + set src in oview(1) + + if(usr.incapacitated()) + return 0 + + if(anchored) + usr << "It is fastened to the floor therefore you can't rotate it!" + return 0 + + set_dir(turn(dir, 90)) + + var/dir_text + if(dir == 1) + dir_text = "north" + else if(dir == 2) + dir_text = "south" + else if(dir == 4) + dir_text = "east" + else if(dir == 8) + dir_text = "west" + + usr << "You rotate the [src] to face [dir_text]!" + + return + + +/obj/structure/frame/verb/revrotate() + set name = "Rotate Frame Clockwise" + set category = "Object" + set src in oview(1) + + if(usr.incapacitated()) + return 0 + + if(anchored) + usr << "It is fastened to the floor therefore you can't rotate it!" + return 0 + + set_dir(turn(dir, 270)) + + var/dir_text + if(dir == 1) + dir_text = "north" + else if(dir == 2) + dir_text = "south" + else if(dir == 4) + dir_text = "east" + else if(dir == 8) + dir_text = "west" + + usr << "You rotate the [src] to face [dir_text]!" + + return \ No newline at end of file diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm index 9700dfd69a..3234d03a1f 100644 --- a/code/game/machinery/suit_storage_unit.dm +++ b/code/game/machinery/suit_storage_unit.dm @@ -586,7 +586,7 @@ var/electrified = 0 //Departments that the cycler can paint suits to look like. - var/list/departments = list("Engineering","Mining","Medical","Security","Atmos","HAZMAT","Construction") + var/list/departments = list("Engineering","Mining","Medical","Security","Atmos","HAZMAT","Construction","Biohazard") //Species that the suits can be configured to fit. var/list/species = list("Human","Skrell","Unathi","Tajara", "Teshari") @@ -634,7 +634,7 @@ name = "Medical suit cycler" model_text = "Medical" req_access = list(access_medical) - departments = list("Medical") + departments = list("Medical","Biohazard") /obj/machinery/suit_cycler/syndicate name = "Nonstandard suit cycler" @@ -751,8 +751,8 @@ //Clear the access reqs, disable the safeties, and open up all paintjobs. user << "You run the sequencer across the interface, corrupting the operating protocols." - departments = list("Engineering","Mining","Medical","Security","Atmos","HAZMAT","Construction","^%###^%$") - species = list("Human","Tajara","Skrell","Unathi", "Teshari") + departments = list("Engineering","Mining","Medical","Security","Atmos","HAZMAT","Construction","Biohazard","^%###^%$") + species = list("Human","Skrell","Unathi","Tajara", "Teshari", "Nevrean", "Akula", "Sergal", "Flatland Zorren", "Highlander Zorren", "Vulpkanin", "Promethean", "Xenomorph Hybrid") //VORESTATION EDIT emagged = 1 safeties = 0 @@ -1036,6 +1036,15 @@ suit.name = "Construction voidsuit" suit.icon_state = "rig-engineering_con" suit.item_state = "eng_voidsuit_con" + if("Biohazard") + if(helmet) + helmet.name = "Biohazard voidsuit helmet" + helmet.icon_state = "rig0-medical_bio" + helmet.item_state = "rig0-medical_bio" + if(suit) + suit.name = "Biohazard voidsuit" + suit.icon_state = "rig-medical_bio" + suit.item_state = "medical_voidsuit_bio" if("^%###^%$" || "Mercenary") if(helmet) helmet.name = "blood-red voidsuit helmet" diff --git a/code/game/machinery/telecomms/presets.dm b/code/game/machinery/telecomms/presets.dm index ca35f59236..4a6aded43b 100644 --- a/code/game/machinery/telecomms/presets.dm +++ b/code/game/machinery/telecomms/presets.dm @@ -25,7 +25,7 @@ autolinkers = list("r_relay") /obj/machinery/telecomms/relay/preset/centcom - id = "Centcom Relay" + id = "CentCom Relay" hide = 1 toggled = 1 //anchored = 1 @@ -44,7 +44,7 @@ "receiverA", "broadcasterA") /obj/machinery/telecomms/hub/preset_cent - id = "CentComm Hub" + id = "CentCom Hub" network = "tcommsat" produces_heat = 0 autolinkers = list("hub_cent", "c_relay", "s_relay", "m_relay", "r_relay", @@ -65,7 +65,7 @@ ..() /obj/machinery/telecomms/receiver/preset_cent - id = "CentComm Receiver" + id = "CentCom Receiver" network = "tcommsat" produces_heat = 0 autolinkers = list("receiverCent") @@ -106,7 +106,7 @@ autolinkers = list("processor4", "engineering", "common") /obj/machinery/telecomms/bus/preset_cent - id = "CentComm Bus" + id = "CentCom Bus" network = "tcommsat" freq_listening = list(ERT_FREQ, DTH_FREQ) produces_heat = 0 @@ -135,7 +135,7 @@ autolinkers = list("processor4") /obj/machinery/telecomms/processor/preset_cent - id = "CentComm Processor" + id = "CentCom Processor" network = "tcommsat" produces_heat = 0 autolinkers = list("processorCent") @@ -200,7 +200,7 @@ autolinkers = list("security") /obj/machinery/telecomms/server/presets/centcomm - id = "CentComm Server" + id = "CentCom Server" freq_listening = list(ERT_FREQ, DTH_FREQ) produces_heat = 0 autolinkers = list("centcomm") @@ -216,7 +216,7 @@ autolinkers = list("broadcasterA") /obj/machinery/telecomms/broadcaster/preset_cent - id = "CentComm Broadcaster" + id = "CentCom Broadcaster" network = "tcommsat" produces_heat = 0 autolinkers = list("broadcasterCent") \ No newline at end of file diff --git a/code/game/objects/effects/decals/posters/tgposters.dm b/code/game/objects/effects/decals/posters/tgposters.dm index 5fb94396d5..50d615efa0 100644 --- a/code/game/objects/effects/decals/posters/tgposters.dm +++ b/code/game/objects/effects/decals/posters/tgposters.dm @@ -41,10 +41,10 @@ /datum/poster/tg_9 name = "Missing Gloves" - desc = "This poster is about the uproar that followed Nanotrasen's financial cuts towards insulated-glove purchases." + desc = "This poster is about the uproar that followed NanoTrasen's financial cuts towards insulated-glove purchases." icon_state="poster9" /datum/poster/tg_10 name = "Hacking Guide" - desc = "This poster details the internal workings of the common Nanotrasen airlock." + desc = "This poster details the internal workings of the common NanoTrasen airlock." icon_state="poster10" \ No newline at end of file diff --git a/code/game/objects/items/devices/PDA/cart.dm b/code/game/objects/items/devices/PDA/cart.dm index a0e37e28b8..94230418e8 100644 --- a/code/game/objects/items/devices/PDA/cart.dm +++ b/code/game/objects/items/devices/PDA/cart.dm @@ -97,6 +97,7 @@ var/list/civilian_cartridges = list( name = "\improper ChemWhiz cartridge" icon_state = "cart-chem" access_reagent_scanner = 1 + access_medical = 1 /obj/item/weapon/cartridge/security name = "\improper R.O.B.U.S.T. cartridge" diff --git a/code/game/objects/items/devices/hacktool.dm b/code/game/objects/items/devices/hacktool.dm index 0cf4af6c74..2f05a6f385 100644 --- a/code/game/objects/items/devices/hacktool.dm +++ b/code/game/objects/items/devices/hacktool.dm @@ -62,7 +62,7 @@ if(hack_result && in_hack_mode) user << "Your hacking attempt was succesful!" - playsound(src.loc, 'sound/piano/A#6.ogg', 75) + user.playsound_local(get_turf(src), 'sound/piano/A#6.ogg', 50) else user << "Your hacking attempt failed!" return 0 diff --git a/code/game/objects/items/devices/powersink.dm b/code/game/objects/items/devices/powersink.dm index a7210721c8..3478abce1d 100644 --- a/code/game/objects/items/devices/powersink.dm +++ b/code/game/objects/items/devices/powersink.dm @@ -18,7 +18,7 @@ var/apc_drain_rate = 5000 // Max. amount drained from single APC. In Watts. var/dissipation_rate = 20000 // Passive dissipation of drained power. In Watts. var/power_drained = 0 // Amount of power drained. - var/max_power = 5e9 // Detonation point. + var/max_power = 1e9 // Detonation point. var/mode = 0 // 0 = off, 1=clamped (off), 2=operating var/drained_this_tick = 0 // This is unfortunately necessary to ensure we process powersinks BEFORE other machinery such as APCs. diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index 7b70216330..5388dc4420 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -143,13 +143,25 @@ REAGENT SCANNER user.show_message("Significant brain damage detected. Subject may have had a concussion.") if(ishuman(M)) var/mob/living/carbon/human/H = M + for(var/name_i in H.internal_organs_by_name) + var/obj/item/organ/internal/i = H.internal_organs_by_name[name_i] + if(istype(i, /obj/item/organ/internal/appendix)) + var/obj/item/organ/internal/appendix/a = H.internal_organs_by_name[name_i] + if(a.inflamed > 3) + user.show_message(text("Severe inflammation detected in subject [a.name]."), 1) + else if(a.inflamed > 2) + user.show_message(text("Moderate inflammation detected in subject [a.name]."), 1) + else if(a.inflamed >= 1) + user.show_message(text("Mild inflammation detected in subject [a.name]."), 1) + + for(var/name in H.organs_by_name) var/obj/item/organ/external/e = H.organs_by_name[name] if(!e) continue var/limb = e.name if(e.status & ORGAN_BROKEN) - if(((e.name == "l_arm") || (e.name == "r_arm") || (e.name == "l_leg") || (e.name == "r_leg")) && (!(e.status & ORGAN_SPLINTED))) + if(((e.name == "l_arm") || (e.name == "r_arm") || (e.name == "l_leg") || (e.name == "r_leg")) && (!e.splinted)) user << "Unsecured fracture in subject [limb]. Splinting recommended for transport." if(e.has_infected_wound()) user << "Infected wound detected in subject [limb]. Disinfection recommended." @@ -165,6 +177,7 @@ REAGENT SCANNER for(var/datum/wound/W in e.wounds) if(W.internal) user.show_message(text("Internal bleeding detected. Advanced scanner required for location."), 1) break + if(M:vessel) var/blood_volume = H.vessel.get_reagent_amount("blood") var/blood_percent = round((blood_volume / H.species.blood_volume)*100) diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm index 3e9c9a7524..41ae7ac7c3 100644 --- a/code/game/objects/items/stacks/medical.dm +++ b/code/game/objects/items/stacks/medical.dm @@ -264,7 +264,7 @@ if(!(affecting.organ_tag in splintable_organs)) user << "You can't use \the [src] to apply a splint there!" return - if(affecting.status & ORGAN_SPLINTED) + if(affecting.splinted) user << "[M]'s [limb] is already splinted!" return if (M != user) @@ -275,17 +275,21 @@ user << "You can't apply a splint to the arm you're using!" return user.visible_message("[user] starts to apply \the [src] to their [limb].", "You start to apply \the [src] to your [limb].", "You hear something being wrapped.") - if(do_after(user, 50)) - if (M != user) - user.visible_message("[user] finishes applying \the [src] to [M]'s [limb].", "You finish applying \the [src] to [M]'s [limb].", "You hear something being wrapped.") - else - if(prob(25)) - user.visible_message("[user] successfully applies \the [src] to their [limb].", "You successfully apply \the [src] to your [limb].", "You hear something being wrapped.") - else - user.visible_message("[user] fumbles \the [src].", "You fumble \the [src].", "You hear something being wrapped.") + if(do_after(user, 50, M)) + if(M == user && prob(75)) + user.visible_message("\The [user] fumbles [src].", "You fumble [src].", "You hear something being wrapped.") + return + var/obj/item/stack/medical/splint/S = split(1) + if(S) + if(affecting.apply_splint(S)) + S.forceMove(affecting) + if (M != user) + user.visible_message("\The [user] finishes applying [src] to [M]'s [limb].", "You finish applying \the [src] to [M]'s [limb].", "You hear something being wrapped.") + else + user.visible_message("\The [user] successfully applies [src] to their [limb].", "You successfully apply \the [src] to your [limb].", "You hear something being wrapped.") return - affecting.status |= ORGAN_SPLINTED - use(1) + S.dropInto(src.loc) //didn't get applied, so just drop it + user.visible_message("\The [user] fails to apply [src].", "You fail to apply [src].", "You hear something being wrapped.") return diff --git a/code/game/objects/items/weapons/cigs_lighters.dm b/code/game/objects/items/weapons/cigs_lighters.dm index f201fbb3c6..3d3cb46192 100644 --- a/code/game/objects/items/weapons/cigs_lighters.dm +++ b/code/game/objects/items/weapons/cigs_lighters.dm @@ -94,6 +94,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM var/zippomes = "USER lights NAME with FLAME" var/weldermes = "USER lights NAME with FLAME" var/ignitermes = "USER lights NAME with FLAME" + var/brand /obj/item/clothing/mask/smokable/New() ..() @@ -169,6 +170,8 @@ CIGARETTE PACKETS ARE IN FANCY.DM if (type_butt) var/obj/item/butt = new type_butt(T) transfer_fingerprints_to(butt) + if(brand) + butt.desc += " This one is \a [brand]." if(ismob(loc)) var/mob/living/M = loc if (!nomessage) diff --git a/code/game/objects/items/weapons/storage/backpack.dm b/code/game/objects/items/weapons/storage/backpack.dm index 69207191e7..6189cc9658 100644 --- a/code/game/objects/items/weapons/storage/backpack.dm +++ b/code/game/objects/items/weapons/storage/backpack.dm @@ -280,3 +280,62 @@ name = "emergency response team medical backpack" desc = "A spacious backpack with lots of pockets, worn by medical members of an Emergency Response Team." icon_state = "ert_medical" + +/* + * Courier Bags + */ + +/obj/item/weapon/storage/backpack/messenger + name = "messenger bag" + desc = "A sturdy backpack worn over one shoulder." + icon_state = "courierbag" + item_state_slots = list(slot_r_hand_str = "backpack", slot_l_hand_str = "backpack") + +/obj/item/weapon/storage/backpack/messenger/chem + name = "chemistry messenger bag" + desc = "A serile backpack worn over one shoulder. This one is in Chemsitry colors." + icon_state = "courierbagchem" + item_state_slots = list(slot_r_hand_str = "chempack", slot_l_hand_str = "chempack") + +/obj/item/weapon/storage/backpack/messenger/med + name = "medical messenger bag" + desc = "A sterile backpack worn over one shoulder used in medical departments." + icon_state = "courierbagmed" + item_state_slots = list(slot_r_hand_str = "medicalpack", slot_l_hand_str = "medicalpack") + +/obj/item/weapon/storage/backpack/messenger/viro + name = "virology messenger bag" + desc = "A sterile backpack worn over one shoulder. This one is in Virology colors." + icon_state = "courierbagviro" + item_state_slots = list(slot_r_hand_str = "viropack", slot_l_hand_str = "viropack") + +/obj/item/weapon/storage/backpack/messenger/tox + name = "research messenger bag" + desc = "A backpack worn over one shoulder. Useful for holding science materials." + icon_state = "courierbagtox" + item_state_slots = list(slot_r_hand_str = "toxpack", slot_l_hand_str = "toxpack") + +/obj/item/weapon/storage/backpack/messenger/com + name = "command messenger bag" + desc = "A special backpack worn over one shoulder. This one is made specifically for officers." + icon_state = "courierbagcom" + item_state_slots = list(slot_r_hand_str = "captainpack", slot_l_hand_str = "captainpack") + +/obj/item/weapon/storage/backpack/messenger/engi + name = "engineering messenger bag" + icon_state = "courierbagengi" + item_state_slots = list(slot_r_hand_str = "engiepack", slot_l_hand_str = "engiepack") + +/obj/item/weapon/storage/backpack/messenger/hyd + name = "hydroponics messenger bag" + desc = "A backpack worn over one shoulder. This one is designed for plant-related work." + icon_state = "courierbaghyd" + +/obj/item/weapon/storage/backpack/messenger/sec + name = "security messenger bag" + desc = "A tactical backpack worn over one shoulder. This one is in Security colors." + icon_state = "courierbagsec" + item_state_slots = list(slot_r_hand_str = "securitypack", slot_l_hand_str = "securitypack") + +/obj/item/weapon/storage/backpack/messenger/black + icon_state = "courierbagblk" \ No newline at end of file diff --git a/code/game/objects/items/weapons/storage/belt.dm b/code/game/objects/items/weapons/storage/belt.dm index f7de0b46f6..6f0beed5e9 100644 --- a/code/game/objects/items/weapons/storage/belt.dm +++ b/code/game/objects/items/weapons/storage/belt.dm @@ -56,6 +56,7 @@ /obj/item/weapon/extinguisher/mini, /obj/item/device/flashlight/maglight, /obj/item/weapon/tape_roll, + /obj/item/device/integrated_electronics/wirer, ) /obj/item/weapon/storage/belt/utility/full/New() @@ -128,6 +129,8 @@ /obj/item/weapon/reagent_containers/food/snacks/donut/, /obj/item/weapon/melee/baton, /obj/item/weapon/gun/energy/taser, + /obj/item/weapon/gun/energy/stunrevolver, + /obj/item/weapon/gun/energy/gun, /obj/item/weapon/flame/lighter, /obj/item/device/flashlight, /obj/item/device/pda, diff --git a/code/game/objects/items/weapons/storage/fancy.dm b/code/game/objects/items/weapons/storage/fancy.dm index 2561886efa..009e1fcc90 100644 --- a/code/game/objects/items/weapons/storage/fancy.dm +++ b/code/game/objects/items/weapons/storage/fancy.dm @@ -134,6 +134,7 @@ storage_slots = 6 can_hold = list(/obj/item/clothing/mask/smokable/cigarette, /obj/item/weapon/flame/lighter) icon_type = "cigarette" + var/brand = "\improper Trans-Stellar Duty-free" /obj/item/weapon/storage/fancy/cigarettes/New() ..() @@ -142,6 +143,10 @@ new /obj/item/clothing/mask/smokable/cigarette(src) create_reagents(15 * storage_slots)//so people can inject cigarettes without opening a packet, now with being able to inject the whole one flags |= OPENCONTAINER + if(brand) + for(var/obj/item/clothing/mask/smokable/cigarette/C in src) + C.brand = brand + C.desc += " This one is \a [brand]." /obj/item/weapon/storage/fancy/cigarettes/update_icon() icon_state = "[initial(icon_state)][contents.len]" @@ -186,11 +191,13 @@ name = "\improper DromedaryCo packet" desc = "A packet of six imported DromedaryCo cancer sticks. A label on the packaging reads, \"Wouldn't a slow death make a change?\"" icon_state = "Dpacket" + brand = "\improper Dromedary Co. cigarette" /obj/item/weapon/storage/fancy/cigarettes/killthroat name = "\improper AcmeCo packet" desc = "A packet of six AcmeCo cigarettes. For those who somehow want to obtain the record for the most amount of cancerous tumors." icon_state = "Bpacket" + brand = "\improper Acme Co. cigarette" // New() // ..() @@ -202,26 +209,31 @@ name = "\improper pack of Lucky Stars" desc = "A mellow blend made from synthetic, pod-grown tobacco. The commercial jingle is guaranteed to get stuck in your head." icon_state = "LSpacket" + brand = "\improper Lucky Star" /obj/item/weapon/storage/fancy/cigarettes/jerichos name = "\improper pack of Jerichos" desc = "Typically seen dangling from the lips of Martian soldiers and border world hustlers. Tastes like hickory smoke, feels like warm liquid death down your lungs." icon_state = "Jpacket" + brand = "\improper Jericho" /obj/item/weapon/storage/fancy/cigarettes/menthols name = "\improper pack of Temperamento Menthols" desc = "With a sharp and natural organic menthol flavor, these Temperamentos are a favorite of NDV crews. Hardly anyone knows they make 'em in non-menthol!" icon_state = "TMpacket" + brand = "\improper Temperamento Menthol" /obj/item/weapon/storage/fancy/cigarettes/carcinomas name = "\improper pack of Carcinoma Angels" desc = "This unknown brand was slated for the chopping block, until they were publicly endorsed by an old Earthling gonzo journalist. The rest is history. They sell a variety for cats, too." icon_state = "CApacket" + brand = "\improper Carcinoma Angel" /obj/item/weapon/storage/fancy/cigarettes/professionals name = "\improper pack of Professional 120s" desc = "Let's face it - if you're smoking these, you're either trying to look upper-class or you're 80 years old. That's the only excuse. They are, however, very good quality." icon_state = "P100packet" + brand = "\improper Professional 120" /obj/item/weapon/storage/fancy/cigar name = "cigar case" diff --git a/code/game/objects/items/weapons/storage/toolbox.dm b/code/game/objects/items/weapons/storage/toolbox.dm index 7d0161a2fd..9c779f013a 100644 --- a/code/game/objects/items/weapons/storage/toolbox.dm +++ b/code/game/objects/items/weapons/storage/toolbox.dm @@ -127,10 +127,10 @@ filled = TRUE /obj/item/weapon/storage/toolbox/lunchbox/nt - name = "Nanotrasen brand lunchbox" + name = "NanoTrasen brand lunchbox" icon_state = "lunchbox_nanotrasen" item_state_slots = list(slot_r_hand_str = "toolbox_blue", slot_l_hand_str = "toolbox_blue") - desc = "A little lunchbox. This one is branded with the Nanotrasen logo!" + desc = "A little lunchbox. This one is branded with the NanoTrasen logo!" /obj/item/weapon/storage/toolbox/lunchbox/nt/filled filled = TRUE diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index d88e8c5372..107ea11520 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -394,3 +394,6 @@ var/shake_dir = pick(-1, 1) animate(src, transform=turn(matrix(), 8*shake_dir), pixel_x=init_px + 2*shake_dir, time=1) animate(transform=null, pixel_x=init_px, time=6, easing=ELASTIC_EASING) + +/obj/structure/closet/onDropInto(var/atom/movable/AM) + return diff --git a/code/game/objects/structures/crates_lockers/closets/wardrobe.dm b/code/game/objects/structures/crates_lockers/closets/wardrobe.dm index a422768269..0f5d5119bb 100644 --- a/code/game/objects/structures/crates_lockers/closets/wardrobe.dm +++ b/code/game/objects/structures/crates_lockers/closets/wardrobe.dm @@ -131,6 +131,7 @@ new /obj/item/clothing/mask/bandana(src) new /obj/item/clothing/mask/bandana(src) new /obj/item/clothing/mask/bandana(src) + new /obj/item/weapon/storage/backpack/messenger/black(src) return @@ -539,6 +540,8 @@ new /obj/item/clothing/under/pants/khaki(src) new /obj/item/clothing/mask/bandana/blue(src) new /obj/item/clothing/mask/bandana/blue(src) + new /obj/item/clothing/accessory/hawaii(src) + new /obj/item/clothing/accessory/hawaii/random(src) return /obj/structure/closet/wardrobe/tactical @@ -603,6 +606,7 @@ new /obj/item/clothing/under/sl_suit(src) new /obj/item/clothing/under/suit_jacket(src) new /obj/item/clothing/under/suit_jacket/female(src) + new /obj/item/clothing/under/suit_jacket/female/skirt(src) new /obj/item/clothing/under/suit_jacket/really_black(src) new /obj/item/clothing/under/suit_jacket/red(src) new /obj/item/clothing/under/scratch(src) diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm index d6034bbb8a..5cdb49657a 100644 --- a/code/game/objects/structures/crates_lockers/crates.dm +++ b/code/game/objects/structures/crates_lockers/crates.dm @@ -265,7 +265,7 @@ /obj/structure/closet/crate/contraband name = "Poster crate" - desc = "A random assortment of posters manufactured by providers NOT listed under Nanotrasen's whitelist." + desc = "A random assortment of posters manufactured by providers NOT listed under NanoTrasen's whitelist." icon_state = "crate" icon_opened = "crateopen" icon_closed = "crate" diff --git a/code/global.dm b/code/global.dm index e2df3f0661..746352df6c 100644 --- a/code/global.dm +++ b/code/global.dm @@ -30,7 +30,7 @@ var/const/station_orig = "Virgo Orbital Research Establishment" //station_name c var/const/station_short = "V.O.R.E." var/const/dock_name = "Virgo-Erigone Central Command" var/const/boss_name = "Central Command" -var/const/boss_short = "Centcom" +var/const/boss_short = "CentCom" var/const/company_name = "NanoTrasen" var/const/company_short = "NT" var/const/star_name = "Virgo-Erigone" diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index eaadf431bc..fe427b54d8 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -440,6 +440,27 @@ counter = 0 jobs += "" + //Cargo (Yellow) + counter = 0 + jobs += "" + jobs += "" + for(var/jobPos in cargo_positions) + if(!jobPos) continue + var/datum/job/job = job_master.GetJob(jobPos) + if(!job) continue + + if(jobban_isbanned(M, job.title)) + jobs += "" + counter++ + else + jobs += "" + counter++ + + if(counter >= 5) //So things dont get squiiiiished! + jobs += "" + counter = 0 + jobs += "
Cargo Positions
[replacetext(job.title, " ", " ")][replacetext(job.title, " ", " ")]
" + //Medical (White) counter = 0 jobs += "" @@ -617,6 +638,12 @@ var/datum/job/temp = job_master.GetJob(jobPos) if(!temp) continue joblist += temp.title + if("cargodept") + for(var/jobPos in cargo_positions) + if(!jobPos) continue + var/datum/job/temp = job_master.GetJob(jobPos) + if(!temp) continue + joblist += temp.title if("medicaldept") for(var/jobPos in medical_positions) if(!jobPos) continue @@ -1323,19 +1350,19 @@ M.Weaken(20) M.stuttering = 20 - else if(href_list["CentcommReply"]) - var/mob/living/L = locate(href_list["CentcommReply"]) + else if(href_list["CentComReply"]) + var/mob/living/L = locate(href_list["CentComReply"]) if(!istype(L)) usr << "This can only be used on instances of type /mob/living/" return if(L.can_centcom_reply()) - var/input = sanitize(input(src.owner, "Please enter a message to reply to [key_name(L)] via their headset.","Outgoing message from Centcomm", "")) + var/input = sanitize(input(src.owner, "Please enter a message to reply to [key_name(L)] via their headset.","Outgoing message from CentCom", "")) if(!input) return src.owner << "You sent [input] to [L] via a secure channel." - log_admin("[src.owner] replied to [key_name(L)]'s Centcomm message with the message [input].") - message_admins("[src.owner] replied to [key_name(L)]'s Centcom message with: \"[input]\"") + log_admin("[src.owner] replied to [key_name(L)]'s CentCom message with the message [input].") + message_admins("[src.owner] replied to [key_name(L)]'s CentCom message with: \"[input]\"") if(!isAI(L)) L << "You hear something crackle in your headset for a moment before a voice speaks." L << "Please stand by for a message from Central Command." diff --git a/code/modules/admin/verbs/pray.dm b/code/modules/admin/verbs/pray.dm index 844f74b5f6..1307086a87 100644 --- a/code/modules/admin/verbs/pray.dm +++ b/code/modules/admin/verbs/pray.dm @@ -27,8 +27,8 @@ feedback_add_details("admin_verb","PR") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! //log_admin("HELP: [key_name(src)]: [msg]") -/proc/Centcomm_announce(var/msg, var/mob/Sender, var/iamessage) - msg = "\blue [uppertext(boss_short)]M[iamessage ? " IA" : ""]:[key_name(Sender, 1)] (PP) (VV) (SM) ([admin_jump_link(Sender, src)]) (CA) (BSA) (RPLY): [msg]" +/proc/CentCom_announce(var/msg, var/mob/Sender, var/iamessage) + msg = "\blue [uppertext(boss_short)]M[iamessage ? " IA" : ""]:[key_name(Sender, 1)] (PP) (VV) (SM) ([admin_jump_link(Sender, src)]) (CA) (BSA) (RPLY): [msg]" for(var/client/C in admins) if(R_ADMIN & C.holder.rights) C << msg diff --git a/code/modules/client/preference_setup/general/04_equipment.dm b/code/modules/client/preference_setup/general/04_equipment.dm index 537f2632e7..79adec9afc 100644 --- a/code/modules/client/preference_setup/general/04_equipment.dm +++ b/code/modules/client/preference_setup/general/04_equipment.dm @@ -34,7 +34,7 @@ pref.all_underwear -= underwear_category_name // TODO - Looks like this is duplicating the work of sanitize_character() if so, remove - if(pref.backbag > 4 || pref.backbag < 1) + if(pref.backbag > 5 || pref.backbag < 1) pref.backbag = 1 //Same as above character.backbag = pref.backbag diff --git a/code/modules/client/preference_setup/loadout/loadout_accessories.dm b/code/modules/client/preference_setup/loadout/loadout_accessories.dm index 769e9966c3..c5a67ad920 100644 --- a/code/modules/client/preference_setup/loadout/loadout_accessories.dm +++ b/code/modules/client/preference_setup/loadout/loadout_accessories.dm @@ -218,4 +218,16 @@ /datum/gear/accessory/chaps/black display_name = "chaps, black" - path = /obj/item/clothing/accessory/chaps/black \ No newline at end of file + path = /obj/item/clothing/accessory/chaps/black + +/datum/gear/accessory/hawaii + display_name = "hawaii shirt" + path = /obj/item/clothing/accessory/hawaii + +/datum/gear/accessory/hawaii/New() + ..() + var/list/shirts = list() + shirts["blue hawaii shirt"] = /obj/item/clothing/accessory/hawaii + shirts["red hawaii shirt"] = /obj/item/clothing/accessory/hawaii/red + shirts["random colored hawaii shirt"] = /obj/item/clothing/accessory/hawaii/random + gear_tweaks += new/datum/gear_tweak/path(shirts) diff --git a/code/modules/client/preference_setup/loadout/loadout_shoes.dm b/code/modules/client/preference_setup/loadout/loadout_shoes.dm index 29c6317b1f..29d6b5944e 100644 --- a/code/modules/client/preference_setup/loadout/loadout_shoes.dm +++ b/code/modules/client/preference_setup/loadout/loadout_shoes.dm @@ -13,6 +13,10 @@ display_name = "workboots" path = /obj/item/clothing/shoes/workboots +/datum/gear/shoes/workboots/toeless + display_name = "toe-less workboots" + path = /obj/item/clothing/shoes/workboots/toeless + /datum/gear/shoes/sandals display_name = "sandals" path = /obj/item/clothing/shoes/sandal @@ -102,5 +106,21 @@ path = /obj/item/clothing/shoes/flipflop /datum/gear/shoes/flipflops/New() + ..() + gear_tweaks = list(gear_tweak_free_color_choice) + +/datum/gear/shoes/athletic + display_name = "athletic shoes" + path = /obj/item/clothing/shoes/athletic + +/datum/gear/shoes/athletic/New() + ..() + gear_tweaks = list(gear_tweak_free_color_choice) + +/datum/gear/shoes/skater + display_name = "skater shoes" + path = /obj/item/clothing/shoes/skater + +/datum/gear/shoes/skater/New() ..() gear_tweaks = list(gear_tweak_free_color_choice) \ No newline at end of file diff --git a/code/modules/client/preference_setup/loadout/loadout_uniform.dm b/code/modules/client/preference_setup/loadout/loadout_uniform.dm index 041751d5c9..c79d4d31b2 100644 --- a/code/modules/client/preference_setup/loadout/loadout_uniform.dm +++ b/code/modules/client/preference_setup/loadout/loadout_uniform.dm @@ -364,4 +364,20 @@ /datum/gear/uniform/whitewedding display_name= "white wedding dress" - path = /obj/item/clothing/under/dress/white \ No newline at end of file + path = /obj/item/clothing/under/dress/white + +/datum/gear/uniform/skirts + display_name = "executive skirt" + path = /obj/item/clothing/under/suit_jacket/female/skirt + +/datum/gear/uniform/dresses + display_name = "sailor dress" + path = /obj/item/clothing/under/dress/sailordress + +/datum/gear/uniform/dresses/eveninggown + display_name = "red evening gown" + path = /obj/item/clothing/under/dress/redeveninggown + +/datum/gear/uniform/dresses/janimaid + display_name = "maid uniform" + path = /obj/item/clothing/under/dress/janimaid \ No newline at end of file diff --git a/code/modules/client/preference_setup/loadout/loadout_xeno.dm b/code/modules/client/preference_setup/loadout/loadout_xeno.dm index b8ed50c23f..cfe92370bf 100644 --- a/code/modules/client/preference_setup/loadout/loadout_xeno.dm +++ b/code/modules/client/preference_setup/loadout/loadout_xeno.dm @@ -126,4 +126,4 @@ display_name = "loincloth (Tajaran, Unathi)" path = /obj/item/clothing/under/shorts/loincloth sort_category = "Xenowear" - whitelisted = list("Tajaran", "Unathi") + //whitelisted = list("Tajaran", "Unathi") //VORESTATION EDIT diff --git a/code/modules/client/preference_setup/occupation/occupation.dm b/code/modules/client/preference_setup/occupation/occupation.dm index f815a3c5ea..444b87754e 100644 --- a/code/modules/client/preference_setup/occupation/occupation.dm +++ b/code/modules/client/preference_setup/occupation/occupation.dm @@ -54,7 +54,7 @@ if(alt_title && !(alt_title in job.alt_titles)) pref.player_alt_titles -= job.title -/datum/category_item/player_setup_item/occupation/content(mob/user, limit = 16, list/splitJobs = list("Chief Medical Officer")) +/datum/category_item/player_setup_item/occupation/content(mob/user, limit = 17, list/splitJobs = list("Chief Medical Officer")) if(!job_master) return diff --git a/code/modules/clothing/head/misc.dm b/code/modules/clothing/head/misc.dm index f65b5373bb..a8305dd9ac 100644 --- a/code/modules/clothing/head/misc.dm +++ b/code/modules/clothing/head/misc.dm @@ -1,5 +1,5 @@ /obj/item/clothing/head/centhat - name = "\improper CentComm. hat" + name = "\improper CentCom. hat" icon_state = "centcom" desc = "It's good to be emperor." siemens_coefficient = 0.9 diff --git a/code/modules/clothing/shoes/jobs.dm b/code/modules/clothing/shoes/jobs.dm index 63d4dc192a..00dc994cad 100644 --- a/code/modules/clothing/shoes/jobs.dm +++ b/code/modules/clothing/shoes/jobs.dm @@ -29,4 +29,11 @@ icon_state = "workboots" armor = list(melee = 40, bullet = 0, laser = 0, energy = 15, bomb = 20, bio = 0, rad = 20) siemens_coefficient = 0.7 - can_hold_knife = 1 \ No newline at end of file + can_hold_knife = 1 + +/obj/item/clothing/shoes/workboots/toeless + name = "toe-less workboots" + desc = "A pair of toeless work boots designed for use in industrial settings. Modified for species whose toes have claws." + icon_state = "workbootstoeless" + item_state_slots = list(slot_r_hand_str = "workboots", slot_l_hand_str = "workboots") + species_restricted = null \ No newline at end of file diff --git a/code/modules/clothing/shoes/miscellaneous.dm b/code/modules/clothing/shoes/miscellaneous.dm index 723d802186..fd8e5c7c40 100644 --- a/code/modules/clothing/shoes/miscellaneous.dm +++ b/code/modules/clothing/shoes/miscellaneous.dm @@ -205,3 +205,15 @@ name = "flip flops" desc = "A pair of foam flip flops. For those not afraid to show a little ankle." icon_state = "thongsandal" + +/obj/item/clothing/shoes/athletic + name = "athletic shoes" + desc = "A pair of sleek atheletic shoes. Made by and for the sporty types." + icon_state = "sportshoe" + item_state_slots = list(slot_r_hand_str = "sportheld", slot_l_hand_str = "sportheld") + +/obj/item/clothing/shoes/skater + name = "skater shoes" + desc = "A pair of wide shoes with thick soles. Designed for skating." + icon_state = "skatershoe" + item_state_slots = list(slot_r_hand_str = "skaterheld", slot_l_hand_str = "skaterheld") diff --git a/code/modules/clothing/spacesuits/rig/suits/station.dm b/code/modules/clothing/spacesuits/rig/suits/station.dm index 17d5d53425..914afe8d97 100644 --- a/code/modules/clothing/spacesuits/rig/suits/station.dm +++ b/code/modules/clothing/spacesuits/rig/suits/station.dm @@ -124,15 +124,16 @@ offline_vision_restriction = 0 helm_type = /obj/item/clothing/head/helmet/space/rig/ce + glove_type = /obj/item/clothing/gloves/gauntlets/rig/ce allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/storage/bag/ore,/obj/item/device/t_scanner,/obj/item/weapon/pickaxe, /obj/item/weapon/rcd) - req_access = list() req_one_access = list() - boot_type = null - glove_type = null +/obj/item/clothing/gloves/gauntlets/rig/ce + name = "insulated gauntlets" + siemens_coefficient = 0 /obj/item/weapon/rig/ce/equipped @@ -146,14 +147,6 @@ /obj/item/rig_module/vision/meson ) - chest_type = /obj/item/clothing/suit/space/rig/ce - boot_type = null - glove_type = null - -/obj/item/clothing/suit/space/rig/ce - heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS - body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS - /obj/item/weapon/rig/hazmat name = "AMI control module" diff --git a/code/modules/clothing/spacesuits/spacesuits.dm b/code/modules/clothing/spacesuits/spacesuits.dm index f06e839ae3..942921b0e9 100644 --- a/code/modules/clothing/spacesuits/spacesuits.dm +++ b/code/modules/clothing/spacesuits/spacesuits.dm @@ -63,7 +63,7 @@ var/list/supporting_limbs //If not-null, automatically splints breaks. Checked when removing the suit. /obj/item/clothing/suit/space/equipped(mob/M) - check_limb_support() + check_limb_support(M) ..() /obj/item/clothing/suit/space/dropped(var/mob/user) @@ -77,14 +77,24 @@ /obj/item/clothing/suit/space/proc/check_limb_support(var/mob/living/carbon/human/user) // If this isn't set, then we don't need to care. - if(!supporting_limbs || !supporting_limbs.len) + if(!istype(user) || isnull(supporting_limbs)) return - if(!istype(user) || user.wear_suit == src) - return + if(user.wear_suit == src) + for(var/obj/item/organ/external/E in user.bad_external_organs) + if(E.is_broken() && E.apply_splint(src)) + user << "You feel [src] constrict about your [E.name], supporting it." + supporting_limbs |= E + else + // Otherwise, remove the splints. + for(var/obj/item/organ/external/E in supporting_limbs) + if(E.splinted == src && E.remove_splint(src)) + user << "\The [src] stops supporting your [E.name]." + supporting_limbs.Cut() - // Otherwise, remove the splints. - for(var/obj/item/organ/external/E in supporting_limbs) - E.status &= ~ ORGAN_SPLINTED - user << "The suit stops supporting your [E.name]." - supporting_limbs = list() +/obj/item/clothing/suit/space/proc/handle_fracture(var/mob/living/carbon/human/user, var/obj/item/organ/external/E) + if(!istype(user) || isnull(supporting_limbs)) + return + if(E.is_broken() && E.apply_splint(src)) + user << "You feel [src] constrict about your [E.name], supporting it." + supporting_limbs |= E diff --git a/code/modules/clothing/spacesuits/void/station.dm b/code/modules/clothing/spacesuits/void/station.dm index f69df89f3f..fd03c3cbe4 100644 --- a/code/modules/clothing/spacesuits/void/station.dm +++ b/code/modules/clothing/spacesuits/void/station.dm @@ -7,7 +7,7 @@ item_state_slots = list(slot_r_hand_str = "eng_helm", slot_l_hand_str = "eng_helm") armor = list(melee = 40, bullet = 5, laser = 20, energy = 5, bomb = 35, bio = 100, rad = 80) -/obj/item/clothing/head/helmet/space/void/engineering/rad +/obj/item/clothing/head/helmet/space/void/engineering/hazmat name = "HAZMAT voidsuit helmet" icon_state = "rig0-engineering_rad" item_state_slots = list(slot_r_hand_str = "eng_helm_rad", slot_l_hand_str = "eng_helm_rad") @@ -26,7 +26,7 @@ armor = list(melee = 40, bullet = 5, laser = 20, energy = 5, bomb = 35, bio = 100, rad = 80) allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/storage/bag/ore,/obj/item/device/t_scanner,/obj/item/weapon/pickaxe, /obj/item/weapon/rcd) -/obj/item/clothing/suit/space/void/engineering/rad +/obj/item/clothing/suit/space/void/engineering/hazmat name = "HAZMAT voidsuit" icon_state = "rig-engineering_rad" item_state_slots = list(slot_r_hand_str = "eng_voidsuit_rad", slot_l_hand_str = "eng_voidsuit_rad") @@ -60,6 +60,11 @@ item_state_slots = list(slot_r_hand_str = "medical_helm", slot_l_hand_str = "medical_helm") armor = list(melee = 30, bullet = 5, laser = 20, energy = 5, bomb = 25, bio = 100, rad = 50) +/obj/item/clothing/head/helmet/space/void/medical/bio + name = "biohazard voidsuit helmet" + icon_state = "rig0-medical_bio" + item_state_slots = list(slot_r_hand_str = "medical_helm_bio", slot_l_hand_str = "medical_helm_bio") + /obj/item/clothing/suit/space/void/medical name = "medical voidsuit" desc = "A special suit that protects against hazardous, low pressure environments. Has minor radiation shielding." @@ -68,6 +73,11 @@ allowed = list(/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit,/obj/item/weapon/storage/firstaid,/obj/item/device/healthanalyzer,/obj/item/stack/medical) armor = list(melee = 30, bullet = 5, laser = 20, energy = 5, bomb = 25, bio = 100, rad = 50) +/obj/item/clothing/suit/space/void/medical/bio + name = "biohazard voidsuit" + icon_state = "rig-medical_bio" + item_state_slots = list(slot_r_hand_str = "medical_voidsuit_bio", slot_l_hand_str = "medical_voidsuit_bio") + //Security /obj/item/clothing/head/helmet/space/void/security name = "security voidsuit helmet" diff --git a/code/modules/clothing/suits/armor.dm b/code/modules/clothing/suits/armor.dm index 3476ea183a..648cf07a41 100644 --- a/code/modules/clothing/suits/armor.dm +++ b/code/modules/clothing/suits/armor.dm @@ -44,7 +44,6 @@ desc = "A vest with heavy padding to protect against melee attacks." icon_state = "riot" item_state_slots = list(slot_r_hand_str = "swat", slot_l_hand_str = "swat") - slowdown = 1 armor = list(melee = 80, bullet = 10, laser = 10, energy = 10, bomb = 0, bio = 0, rad = 0) flags_inv = HIDEJUMPSUIT siemens_coefficient = 0.5 @@ -323,6 +322,12 @@ icon_badge = "detectivevest_badge" icon_nobadge = "detectivevest_nobadge" +/obj/item/clothing/suit/storage/vest/press + name = "press vest" + desc = "A simple kevlar plate carrier. This one has the word 'Press' embroidered on patches on the back and front." + item_state_slots = list(slot_r_hand_str = "armor", slot_l_hand_str = "armor") + allowed = list(/obj/item/device/flashlight,/obj/item/device/taperecorder,/obj/item/weapon/pen,/obj/item/device/camera_film,/obj/item/device/camera) + /obj/item/clothing/suit/storage/vest/heavy name = "heavy armor vest" desc = "A heavy kevlar plate carrier with webbing attached." diff --git a/code/modules/clothing/suits/miscellaneous.dm b/code/modules/clothing/suits/miscellaneous.dm index fecc19b5a2..2dc9e22404 100644 --- a/code/modules/clothing/suits/miscellaneous.dm +++ b/code/modules/clothing/suits/miscellaneous.dm @@ -90,6 +90,7 @@ icon_state = "vest" item_state_slots = list(slot_r_hand_str = "wcoat", slot_l_hand_str = "wcoat") blood_overlay_type = "armor" + allowed = list (/obj/item/weapon/pen, /obj/item/weapon/paper, /obj/item/device/flashlight, /obj/item/weapon/tank/emergency_oxygen, /obj/item/weapon/storage/fancy/cigarettes, /obj/item/weapon/storage/box/matches, /obj/item/weapon/reagent_containers/food/drinks/flask) body_parts_covered = UPPER_TORSO|LOWER_TORSO /obj/item/clothing/suit/wcoat/red @@ -203,6 +204,7 @@ name = "leather coat" desc = "A long, thick black leather coat." icon_state = "leathercoat_alt" + allowed = list (/obj/item/weapon/pen, /obj/item/weapon/paper, /obj/item/device/flashlight, /obj/item/weapon/tank/emergency_oxygen, /obj/item/weapon/storage/fancy/cigarettes, /obj/item/weapon/storage/box/matches, /obj/item/weapon/reagent_containers/food/drinks/flask) item_state_slots = list(slot_r_hand_str = "leather_jacket", slot_l_hand_str = "leather_jacket") /obj/item/clothing/suit/leathercoat/sec @@ -215,12 +217,14 @@ name = "brown leather coat" desc = "A long, brown leather coat." icon_state = "browncoat" + allowed = list (/obj/item/weapon/pen, /obj/item/weapon/paper, /obj/item/device/flashlight,/obj/item/weapon/tank/emergency_oxygen, /obj/item/weapon/storage/fancy/cigarettes, /obj/item/weapon/storage/box/matches, /obj/item/weapon/reagent_containers/food/drinks/flask) item_state_slots = list(slot_r_hand_str = "brown_jacket", slot_l_hand_str = "brown_jacket") /obj/item/clothing/suit/neocoat name = "black coat" desc = "A flowing, black coat." icon_state = "neocoat" + allowed = list (/obj/item/weapon/pen, /obj/item/weapon/paper, /obj/item/device/flashlight, /obj/item/weapon/tank/emergency_oxygen, /obj/item/weapon/storage/fancy/cigarettes, /obj/item/weapon/storage/box/matches, /obj/item/weapon/reagent_containers/food/drinks/flask) item_state_slots = list(slot_r_hand_str = "leather_jacket", slot_l_hand_str = "leather_jacket") /obj/item/clothing/suit/customs @@ -292,6 +296,7 @@ item_state_slots = list(slot_r_hand_str = "brown_jacket", slot_l_hand_str = "brown_jacket") icon_open = "bomber_open" icon_closed = "bomber" + allowed = list (/obj/item/weapon/pen, /obj/item/weapon/paper, /obj/item/device/flashlight, /obj/item/weapon/tank/emergency_oxygen, /obj/item/weapon/storage/fancy/cigarettes, /obj/item/weapon/storage/box/matches, /obj/item/weapon/reagent_containers/food/drinks/flask) body_parts_covered = UPPER_TORSO|ARMS cold_protection = UPPER_TORSO|ARMS min_cold_protection_temperature = T0C - 20 @@ -311,6 +316,7 @@ name = "leather jacket" desc = "A black leather coat." icon_state = "leather_jacket" + allowed = list (/obj/item/weapon/pen, /obj/item/weapon/paper, /obj/item/device/flashlight, /obj/item/weapon/tank/emergency_oxygen, /obj/item/weapon/storage/fancy/cigarettes, /obj/item/weapon/storage/box/matches, /obj/item/weapon/reagent_containers/food/drinks/flask) body_parts_covered = UPPER_TORSO|ARMS /obj/item/clothing/suit/storage/leather_jacket/alt @@ -330,6 +336,7 @@ item_state_slots = list(slot_r_hand_str = "brown_jacket", slot_l_hand_str = "brown_jacket") icon_open = "brown_jacket_open" icon_closed = "brown_jacket" + allowed = list (/obj/item/weapon/pen, /obj/item/weapon/paper, /obj/item/device/flashlight,/obj/item/weapon/tank/emergency_oxygen, /obj/item/weapon/storage/fancy/cigarettes, /obj/item/weapon/storage/box/matches, /obj/item/weapon/reagent_containers/food/drinks/flask) body_parts_covered = UPPER_TORSO|ARMS /obj/item/clothing/suit/storage/toggle/brown_jacket/nanotrasen @@ -491,6 +498,7 @@ hooded = 1 action_button_name = "Toggle Winter Hood" hoodtype = /obj/item/clothing/head/winterhood + allowed = list (/obj/item/weapon/pen, /obj/item/weapon/paper, /obj/item/device/flashlight,/obj/item/weapon/tank/emergency_oxygen, /obj/item/weapon/storage/fancy/cigarettes, /obj/item/weapon/storage/box/matches, /obj/item/weapon/reagent_containers/food/drinks/flask) /obj/item/clothing/head/winterhood name = "winter hood" @@ -556,6 +564,7 @@ name = "black varsity jacket" desc = "A favorite of jocks everywhere from Sol to Nyx." icon_state = "varsity" + allowed = list (/obj/item/weapon/pen, /obj/item/weapon/paper, /obj/item/device/flashlight,/obj/item/weapon/tank/emergency_oxygen, /obj/item/weapon/storage/fancy/cigarettes, /obj/item/weapon/storage/box/matches, /obj/item/weapon/reagent_containers/food/drinks/flask) item_state_slots = list(slot_r_hand_str = "suit_black", slot_l_hand_str = "suit_black") /obj/item/clothing/suit/varsity/red @@ -588,6 +597,7 @@ item_state_slots = list(slot_r_hand_str = "black_labcoat", slot_l_hand_str = "black_labcoat") icon_open = "trackjacket_open" icon_closed = "trackjacket" + allowed = list (/obj/item/weapon/pen, /obj/item/weapon/paper, /obj/item/device/flashlight,/obj/item/weapon/tank/emergency_oxygen, /obj/item/weapon/storage/fancy/cigarettes, /obj/item/weapon/storage/box/matches, /obj/item/weapon/reagent_containers/food/drinks/flask) /obj/item/clothing/suit/storage/toggle/track/blue name = "blue track jacket" @@ -624,6 +634,7 @@ desc = "A comfy, grey flannel shirt. Unleash your inner hipster." icon_state = "flannel" item_state_slots = list(slot_r_hand_str = "black_labcoat", slot_l_hand_str = "black_labcoat") + allowed = list (/obj/item/weapon/pen, /obj/item/weapon/paper, /obj/item/device/flashlight,/obj/item/weapon/tank/emergency_oxygen, /obj/item/weapon/storage/fancy/cigarettes, /obj/item/weapon/storage/box/matches, /obj/item/weapon/reagent_containers/food/drinks/flask) var/rolled = 0 var/tucked = 0 var/buttoned = 0 diff --git a/code/modules/clothing/suits/utility.dm b/code/modules/clothing/suits/utility.dm index e732a1318e..53ea2d85b6 100644 --- a/code/modules/clothing/suits/utility.dm +++ b/code/modules/clothing/suits/utility.dm @@ -78,7 +78,6 @@ name = "Radiation Hood" icon_state = "rad" desc = "A hood with radiation protective properties. Label: Made with lead, do not eat insulation" - flags_inv = BLOCKHAIR body_parts_covered = HEAD|FACE|EYES armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 60, rad = 100) diff --git a/code/modules/clothing/under/accessories/clothing.dm b/code/modules/clothing/under/accessories/clothing.dm index 9878420d7c..af5b6c1c7a 100644 --- a/code/modules/clothing/under/accessories/clothing.dm +++ b/code/modules/clothing/under/accessories/clothing.dm @@ -112,4 +112,20 @@ name = "cargo poncho" desc = "A simple, comfortable cloak without sleeves. This one is tan and grey, the colors of Cargo." icon_state = "cargoponcho" - item_state = "cargoponcho" \ No newline at end of file + item_state = "cargoponcho" + +/obj/item/clothing/accessory/hawaii + name = "flower-pattern shirt" + desc = "You probably need some welder googles to look at this." + icon_state = "hawaii" + +/obj/item/clothing/accessory/hawaii/red + icon_state = "hawaii2" + +/obj/item/clothing/accessory/hawaii/random + name = "flower-pattern shirt" + +/obj/item/clothing/accessory/hawaii/random/New() + if(prob(50)) + icon_state = "hawaii2" + color = color_rotation(rand(-11,12)*15) \ No newline at end of file diff --git a/code/modules/clothing/under/miscellaneous.dm b/code/modules/clothing/under/miscellaneous.dm index e673de378c..4b22d93877 100644 --- a/code/modules/clothing/under/miscellaneous.dm +++ b/code/modules/clothing/under/miscellaneous.dm @@ -182,6 +182,13 @@ icon_state = "black_suit_fem" item_state_slots = list(slot_r_hand_str = "lawyer_black", slot_l_hand_str = "lawyer_black") +/obj/item/clothing/under/suit_jacket/female/skirt + name = "executive skirt" + desc = "A formal suit skirt for women, intended for the station's finest." + body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS + icon_state = "black_suit_fem" + item_state = "black_formal_skirt" + /obj/item/clothing/under/suit_jacket/red name = "red suit" desc = "A red suit and blue tie. Somewhat formal." diff --git a/code/modules/clothing/under/pants.dm b/code/modules/clothing/under/pants.dm index 3c210cc0c0..3d35b489d6 100644 --- a/code/modules/clothing/under/pants.dm +++ b/code/modules/clothing/under/pants.dm @@ -6,26 +6,51 @@ gender = PLURAL body_parts_covered = LOWER_TORSO|LEGS +/obj/item/clothing/under/pants/ripped + name = "ripped jeans" + desc = "A nondescript pair of tough blue jeans with holes in them." + icon_state = "jeansripped" + /obj/item/clothing/under/pants/classicjeans name = "classic jeans" desc = "You feel cooler already." icon_state = "jeansclassic" +/obj/item/clothing/under/pants/classicjeans/ripped + name = "ripped classic jeans" + desc = "You feel cooler already. These have holes in them." + icon_state = "jeansclassicripped" + /obj/item/clothing/under/pants/mustangjeans name = "must hang jeans" desc = "Made in the finest space jeans factory this side of Alpha Centauri." icon_state = "jeansmustang" +/obj/item/clothing/under/pants/mustangjeans/ripped + name = "ripped must hang jeans" + desc = "Made in the finest space jeans factory this side of Alpha Centauri. These have holes in them." + icon_state = "jeansmustangripped" + /obj/item/clothing/under/pants/blackjeans name = "black jeans" desc = "Only for those who can pull it off." icon_state = "jeansblack" +/obj/item/clothing/under/pants/blackjeans/ripped + name = "ripped black jeans" + desc = "Only for those who can pull it off. These have holes in them." + icon_state = "jeansblackripped" + /obj/item/clothing/under/pants/greyjeans name = "grey jeans" desc = "Only for those who can pull it off." icon_state = "jeansgrey" +/obj/item/clothing/under/pants/greyjeans/ripped + name = "ripped grey jeans" + desc = "Only for those who can pull it off. These have holes in them." + icon_state = "jeansgreyripped" + /obj/item/clothing/under/pants/youngfolksjeans name = "young folks jeans" desc = "For those tired of boring old jeans. Relive the passion of your youth!" diff --git a/code/modules/clothing/under/shorts.dm b/code/modules/clothing/under/shorts.dm index e108c7f33e..0db35dd08c 100644 --- a/code/modules/clothing/under/shorts.dm +++ b/code/modules/clothing/under/shorts.dm @@ -25,6 +25,10 @@ name = "grey athletic shorts" icon_state = "greyshorts" +/obj/item/clothing/under/shorts/white + name = "white shorts" + icon_state = "whiteshorts" + /obj/item/clothing/under/shorts/jeans name = "jeans shorts" desc = "Some jeans! Just in short form!" diff --git a/code/modules/economy/TradeDestinations.dm b/code/modules/economy/TradeDestinations.dm index ccedfe35ef..8ae548e2ff 100644 --- a/code/modules/economy/TradeDestinations.dm +++ b/code/modules/economy/TradeDestinations.dm @@ -18,7 +18,7 @@ var/list/weighted_mundaneevent_locations = list() //distance is measured in AU and co-relates to travel time /datum/trade_destination/centcomm - name = "CentComm" + name = "CentCom" description = "NanoTrasen's administrative centre for Tau Ceti." distance = 1.2 willing_to_buy = list() diff --git a/code/modules/examine/descriptions/devices.dm b/code/modules/examine/descriptions/devices.dm index 05182df0a5..33954f6672 100644 --- a/code/modules/examine/descriptions/devices.dm +++ b/code/modules/examine/descriptions/devices.dm @@ -8,7 +8,7 @@ that while in space, across star systems, and that the consumer can afford and use without training, is much more recent, and is thanks to the backbone \ that is the Exonet.
\
\ - The Exonet is the predominant interstellar telecom system, servicing trillions of devices across a large portion of human-controlled space. \ + The Exonet is the predominant interstellar telecomm system, servicing trillions of devices across a large portion of human-controlled space. \ It is distributed by a massive network of telecommunication satellites, some privately owned and others owned by the systems’ local governments, \ that utilize FTL technologies to bounce data between satellites at speeds that would not be possible at sub-light technology. This communicator \ uses a protocol called Exonet Protocol Version 2, generally shortened to EPv2.
\ diff --git a/code/modules/examine/descriptions/telecomms.dm b/code/modules/examine/descriptions/telecomms.dm index 747697f55f..45101ec130 100644 --- a/code/modules/examine/descriptions/telecomms.dm +++ b/code/modules/examine/descriptions/telecomms.dm @@ -30,7 +30,7 @@ Exonets at the root node(s), and is typically arranged in a tree structure. The root node(s) are generally government-owned and are very secure \ and resilient to failure.
\
\ - This node is privately owned and maintained by Nanotrasen, and allows the colonists of the "+station_orig+" to have access to the Exonet." + This node is privately owned and maintained by NanoTrasen, and allows the colonists of the "+station_orig+" to have access to the Exonet." description_antag = "An EMP will disable this device for a short period of time. A longer downage can be achieved by turning it off, or rigging \ the APC it uses to turn off remotely, such as with a signaler in the right wire." \ No newline at end of file diff --git a/code/modules/games/cards.dm b/code/modules/games/cards.dm index 3fcf07713b..42bd4b709b 100644 --- a/code/modules/games/cards.dm +++ b/code/modules/games/cards.dm @@ -146,7 +146,7 @@ for(var/datum/playingcard/P in cards) H.cards += P H.concealed = src.concealed - user.drop_from_inventory(src,user.loc) + user.drop_from_inventory(src) qdel(src) H.update_icon() return diff --git a/code/modules/integrated_electronics/_defines.dm b/code/modules/integrated_electronics/_defines.dm new file mode 100644 index 0000000000..97acfd2c98 --- /dev/null +++ b/code/modules/integrated_electronics/_defines.dm @@ -0,0 +1,387 @@ +#define DATA_CHANNEL "data channel" +#define PULSE_CHANNEL "pulse channel" + +/obj/item/integrated_circuit + name = "integrated circuit" + desc = "It's a tiny chip! This one doesn't seem to do much, however." + icon = 'icons/obj/electronic_assemblies.dmi' + icon_state = "template" + w_class = 1 + var/extended_desc = null + var/list/inputs = list() + var/list/outputs = list() + var/list/activators = list() + var/number_of_inputs = 0 //This is how many input pins are created + var/number_of_outputs = 0 //Likewise for output + var/number_of_activators = 0 //Guess + var/list/input_names = list() + var/list/output_names = list() + var/list/activator_names = list() + var/last_used = 0 //Uses world.time + var/complexity = 1 //This acts as a limitation on building machines, more resource-intensive components cost more 'space'. + var/cooldown_per_use = 2 SECONDS + +/obj/item/integrated_circuit/examine(mob/user) + ..() + user << "This board has [inputs.len] input [inputs.len != 1 ? "pins" : "pin"] and \ + [outputs.len] output [outputs.len != 1 ? "pins" : "pin"]." + for(var/datum/integrated_io/input/I in inputs) + if(I.linked.len) + user << "\The [I.name] is connected to [I.get_linked_to_desc()]." + for(var/datum/integrated_io/output/O in outputs) + if(O.linked.len) + user << "\The [O.name] is connected to [O.get_linked_to_desc()]." + for(var/datum/integrated_io/activate/A in activators) + if(A.linked.len) + user << "\The [A.name] is connected to [A.get_linked_to_desc()]." + + interact(user) + +/obj/item/integrated_circuit/New() + ..() + var/i = 0 + if(number_of_inputs) + for(i = number_of_inputs, i > 0, i--) + inputs.Add(new /datum/integrated_io/input(src)) + + if(number_of_outputs) + for(i = number_of_outputs, i > 0, i--) + outputs.Add(new /datum/integrated_io/output(src)) + + if(number_of_activators) + for(i = number_of_activators, i > 0, i--) + activators.Add(new /datum/integrated_io/activate(src)) + + apply_names_to_io() + +/obj/item/integrated_circuit/proc/apply_names_to_io() + var/i = 1 + if(input_names.len) + for(var/datum/integrated_io/input/I in inputs) + I.name = "[input_names[i]]" + i++ + i = 1 + if(output_names.len) + for(var/datum/integrated_io/output/O in outputs) + O.name = "[output_names[i]]" + i++ + + i = 1 + if(activator_names.len) + for(var/datum/integrated_io/activate/A in activators) + A.name = "[activator_names[i]]" + i++ + +/obj/item/integrated_circuit/proc/on_data_written() //Override this for special behaviour when new data gets pushed to the circuit. + return + +/obj/item/integrated_circuit/Destroy() + for(var/datum/integrated_io/I in inputs) + qdel(I) + for(var/datum/integrated_io/O in outputs) + qdel(O) + for(var/datum/integrated_io/A in activators) + qdel(A) + ..() + +/obj/item/integrated_circuit/emp_act(severity) + for(var/datum/integrated_io/io in inputs + outputs + activators) + io.scramble() + +/obj/item/integrated_circuit/verb/rename_component() + set name = "Rename Circuit" + set category = "Object" + set desc = "Rename your circuit, useful to stay organized." + + var/mob/M = usr + + if(!M.canmove || M.stat || M.restrained()) + return + + var/input = sanitizeSafe(input("What do you want to name the circuit?", "Rename", src.name), MAX_NAME_LEN) + + if(src && input) + M << "The circuit '[src.name]' is now labeled '[input]'." + name = input + +/obj/item/integrated_circuit/proc/get_pin_ref(var/pin_type, var/pin_number) + switch(pin_type) + if("input") + if(pin_number > inputs.len) + return null + return inputs[pin_number] + if("output") + if(pin_number > outputs.len) + return null + return outputs[pin_number] + if("activator") + if(pin_number > activators.len) + return null + return activators[pin_number] + return null + +/obj/item/integrated_circuit/interact(mob/user) + if(get_dist(get_turf(src), user) > 1) + user.unset_machine(src) + return + var/HTML = "[src.name]" + HTML += "
" + HTML += "
" + + HTML += "
\[Refresh\] | " + HTML += "\[Rename\]
" + + HTML += "" + HTML += "" + HTML += "" + HTML += "" + HTML += "" + + var/column_width = 3 + var/row_height = max(inputs.len, outputs.len, 1) + var/i + var/j + for(i = 1, i < row_height+1, i++) + HTML += "" + for(j = 1, j < column_width+1, j++) + var/datum/integrated_io/io = null + var/words = null + var/height = 1 + switch(j) + if(1) + io = get_pin_ref("input",i) + if(io) + if(io.linked.len) + words = "[io.name] [io.display_data()]
" + for(var/datum/integrated_io/linked in io.linked) + words += "\[[linked.name]\] \ + @ [linked.holder]
" + else // "Click here!" + words = "[io.name] [io.display_data()]
" + for(var/datum/integrated_io/linked in io.linked) + words += "\[[linked.name]\] \ + @ [linked.holder]
" + if(outputs.len > inputs.len) + // height = Floor(outputs.len / inputs.len) + height = 1 // Because of bugs, if there's more outputs than inputs, it causes the output side to be hidden. + //world << "I wrote [words] at ([i],[j]). Height = [height]." + if(2) + if(i == 1) + words = "[src.name]

[src.desc]" + height = row_height + //world << "I wrote the center piece because i was equal to 1, at ([i],[j]). Height = [height]." + else + continue + if(3) + io = get_pin_ref("output",i) + if(io) + if(io.linked.len) + words = "[io.name] [io.display_data()]
" + for(var/datum/integrated_io/linked in io.linked) + words += "\[[linked.name]\] \ + @ [linked.holder]
" + else + words = "[io.name] [io.display_data()]
" + for(var/datum/integrated_io/linked in io.linked) + words += "\[[linked.name]\] \ + @ [linked.holder]
" + if(inputs.len > outputs.len) + // height = Floor(inputs.len / outputs.len) + height = 1 // See above. + //world << "I wrote [words] at ([i],[j]). Height = [height]." + HTML += "" + //HTML += "" + //world << "Writing to ([i],[j])." + HTML += "" + + if(activators.len) + for(i = 1, i < activators.len+1, i++) + var/datum/integrated_io/io = null + var/words = null + io = get_pin_ref("activator",i) + if(io) + if(io.linked.len) + words = "[io.name]
" + for(var/datum/integrated_io/linked in io.linked) + words += "\[[linked.name]\] \ + @ [linked.holder]
" + else // "Click here!" + words = "[io.name]
" + for(var/datum/integrated_io/linked in io.linked) + words += "\[[linked.name]\] \ + @ [linked.holder]
" + HTML += "" + HTML += "" + HTML += "" + + HTML += "
[words][words]
[words]
" + HTML += "" + + HTML += "
Complexity: [complexity]" + HTML += "
[extended_desc]" + + HTML += "" + user << browse(HTML, "window=circuit-\ref[src];size=600x350;border=1;can_resize=1;can_close=1;can_minimize=1") + + //user << sanitize(HTML, "window=debug;size=400x400;border=1;can_resize=1;can_close=1;can_minimize=1") + //world << sanitize(HTML) + + user.set_machine(src) + onclose(user, "circuit-\ref[src]") + +/obj/item/integrated_circuit/Topic(href, href_list[]) + var/mob/living/user = locate(href_list["user"]) in mob_list + var/pin = locate(href_list["pin"]) in inputs + outputs + activators + + if(!user || !user.Adjacent(get_turf(src)) ) + return 1 + + if(!user.canmove || user.stat || user.restrained()) + return + + if(href_list["wire"]) + if(ishuman(user) && Adjacent(user)) + var/mob/living/carbon/human/H = user + var/obj/held_item = H.get_active_hand() + + if(istype(held_item, /obj/item/device/integrated_electronics/wirer)) + var/obj/item/device/integrated_electronics/wirer/wirer = held_item + if(pin) + wirer.wire(pin, user) + + else if(istype(held_item, /obj/item/device/integrated_electronics/debugger)) + var/obj/item/device/integrated_electronics/debugger/debugger = held_item + if(pin) + debugger.write_data(pin, user) + + // if(istype(H.r_hand, /obj/item/device/integrated_electronics/wirer)) + // wirer = H.r_hand + // else if(istype(H.l_hand, /obj/item/device/integrated_electronics/wirer)) + // wirer = H.l_hand + + // if(wirer && pin) + // wirer.wire(pin, user) + else + user << "You can't do a whole lot without tools." + + if(href_list["examine"]) + examine(user) + + if(href_list["rename"]) + rename_component(user) + + interact(user) // To refresh the UI. + +/datum/integrated_io + var/name = "input/output" + var/obj/item/integrated_circuit/holder = null + var/data = null + var/list/linked = list() + var/io_type = DATA_CHANNEL + +/datum/integrated_io/New(var/newloc) + ..() + holder = newloc + if(!holder) + message_admins("ERROR: An integrated_io ([src.name]) spawned without a holder! This is a bug.") + +/datum/integrated_io/Destroy() + disconnect() + holder = null + ..() + +/datum/integrated_io/proc/display_data() + if(isnull(data)) + return "(null)" // Empty data means nothing to show. + if(istext(data)) + return "(\"[data]\")" // Wraps the 'string' in escaped quotes, so that people know it's a 'string'. + if(istype(data, /atom)) + var/atom/A = data + return "([A.name] \[Ref\])" // For refs, we want just the name displayed. + return "([data])" // Nothing special needed for numbers or other stuff. + +/datum/integrated_io/activate/display_data() + return "(\[pulse\])" + +/datum/integrated_io/proc/scramble() + if(isnull(data)) + return + if(isnum(data)) + write_data_to_pin(rand(-10000, 10000)) + if(istext(data)) + write_data_to_pin("ERROR") + push_data() + +/datum/integrated_io/activate/scramble() + push_data() + +/datum/integrated_io/proc/write_data_to_pin(var/new_data) + if(isnull(new_data) || isnum(new_data) || istext(new_data) || istype(new_data, /atom/) ) // Anything else is a type we don't want. + data = new_data + holder.on_data_written() + +/datum/integrated_io/proc/push_data() + if(linked.len) + for(var/datum/integrated_io/io in linked) + io.write_data_to_pin(data) + +/datum/integrated_io/activate/push_data() + if(linked.len) + for(var/datum/integrated_io/io in linked) + io.holder.work() + +/datum/integrated_io/proc/pull_data() + if(linked.len) + for(var/datum/integrated_io/io in linked) + write_data_to_pin(io.data) + +/datum/integrated_io/proc/get_linked_to_desc() + if(linked.len) + var/result = english_list(linked) + return "the [result]" + return "nothing" + +/datum/integrated_io/proc/disconnect() + if(linked.len) + //First we iterate over everything we are linked to. + for(var/datum/integrated_io/their_io in linked) + //While doing that, we iterate them as well, and disconnect ourselves from them. + for(var/datum/integrated_io/their_linked_io in their_io.linked) + if(their_linked_io == src) + their_io.linked.Remove(src) + else + continue + //Now that we're removed from them, we gotta remove them from us. + src.linked.Remove(their_io) + +/datum/integrated_io/input + name = "input pin" + +/datum/integrated_io/output + name = "output pin" + +/datum/integrated_io/activate + name = "activation pin" + io_type = PULSE_CHANNEL + +/obj/item/integrated_circuit/proc/push_data() + for(var/datum/integrated_io/output/O in outputs) + O.push_data() + +/obj/item/integrated_circuit/proc/pull_data() + for(var/datum/integrated_io/input/I in inputs) + I.push_data() + +/obj/item/integrated_circuit/proc/work(var/datum/integrated_io/io) + if(last_used + cooldown_per_use > world.time) // All intergrated circuits have an internal cooldown, to protect from spam. + return 0 + last_used = world.time + return 1 + +/obj/item/integrated_circuit/proc/disconnect_all() + for(var/datum/integrated_io/input/I in inputs) + I.disconnect() + for(var/datum/integrated_io/output/O in outputs) + O.disconnect() + for(var/datum/integrated_io/activate/A in activators) + A.disconnect() \ No newline at end of file diff --git a/code/modules/integrated_electronics/arithmetic.dm b/code/modules/integrated_electronics/arithmetic.dm new file mode 100644 index 0000000000..3fc60c64f9 --- /dev/null +++ b/code/modules/integrated_electronics/arithmetic.dm @@ -0,0 +1,183 @@ +//These circuits do simple math. +/obj/item/integrated_circuit/arithmetic + complexity = 1 + number_of_inputs = 8 + number_of_outputs = 1 + number_of_activators = 1 + input_names = list( + "A", + "B", + "C", + "D", + "E", + "F", + "G", + "H" + ) + output_names = list( + "result" + ) + activator_names = list( + "compute" + ) + +// +Adding+ // + +/obj/item/integrated_circuit/arithmetic/addition + name = "addition circuit" + desc = "This circuit can add numbers together." + icon_state = "addition" + +/obj/item/integrated_circuit/arithmetic/addition/work() + if(..()) + var/result = 0 + for(var/datum/integrated_io/input/I in inputs) + I.pull_data() + if(isnum(I.data)) + result = result + I.data + + for(var/datum/integrated_io/output/O in outputs) + O.data = result + O.push_data() + +// -Subtracting- // + +/obj/item/integrated_circuit/arithmetic/subtraction + name = "subtraction circuit" + desc = "This circuit can subtract numbers." + icon_state = "subtraction" + +/obj/item/integrated_circuit/arithmetic/subtraction/work() + if(..()) + var/result = 0 + for(var/datum/integrated_io/input/I in inputs) + I.pull_data() + if(isnum(I.data)) + result = result - I.data + + for(var/datum/integrated_io/output/O in outputs) + O.data = result + O.push_data() + +// *Multiply* // + +/obj/item/integrated_circuit/arithmetic/multiplication + name = "multiplication circuit" + desc = "This circuit can multiply numbers." + icon_state = "multiplication" + +/obj/item/integrated_circuit/arithmetic/subtraction/work() + if(..()) + var/result = 0 + for(var/datum/integrated_io/input/I in inputs) + I.pull_data() + if(isnum(I.data)) + result = result * I.data + + for(var/datum/integrated_io/output/O in outputs) + O.data = result + O.push_data() + +// /Division/ // + +/obj/item/integrated_circuit/arithmetic/division + name = "division circuit" + desc = "This circuit can divide numbers, just don't think about trying to divide by zero!" + icon_state = "division" + +/obj/item/integrated_circuit/arithmetic/division/work() + if(..()) + var/result = 0 + for(var/datum/integrated_io/input/I in inputs) + I.pull_data() + if(isnum(I.data) && I.data != 0) //No runtimes here. + result = result / I.data + + for(var/datum/integrated_io/output/O in outputs) + O.data = result + O.push_data() + +// Absolute // + +/obj/item/integrated_circuit/arithmetic/absolute + name = "absolute circuit" + desc = "This outputs a non-negative version of the number you put in. This may also be thought of as its distance from zero." + icon_state = "absolute" + number_of_inputs = 1 + number_of_outputs = 1 + +/obj/item/integrated_circuit/arithmetic/absolute/work() + if(..()) + var/result = 0 + for(var/datum/integrated_io/input/I in inputs) + I.pull_data() + if(isnum(I.data) && I.data != 0) + result = abs(result) + + for(var/datum/integrated_io/output/O in outputs) + O.data = result + O.push_data() + +// Averaging // + +/obj/item/integrated_circuit/arithmetic/average + name = "average circuit" + desc = "This circuit is of average quality, however it will compute the average for numbers you give it." + icon_state = "average" + +/obj/item/integrated_circuit/arithmetic/average/work() + if(..()) + var/result = 0 + var/inputs_used = 0 + for(var/datum/integrated_io/input/I in inputs) + I.pull_data() + if(isnum(I.data)) + inputs_used++ + result = result + I.data + + if(inputs_used) + result = result / inputs_used + + for(var/datum/integrated_io/output/O in outputs) + O.data = result + O.push_data() + +// Pi, because why the hell not? // +/obj/item/integrated_circuit/arithmetic/pi + name = "pi constant circuit" + desc = "Not recommended for cooking. Outputs '3.14159' when it receives a pulse." + icon_state = "pi" + number_of_inputs = 0 + number_of_outputs = 1 + +/obj/item/integrated_circuit/arithmetic/pi/work() + if(..()) + var/datum/integrated_io/output/O = outputs[1] + O.data = 3.14159 + O.push_data() + +// Random // +/obj/item/integrated_circuit/arithmetic/random + name = "random number generator circuit" + desc = "This gives a random (integer) number between values A and B inclusive." + icon_state = "random" + number_of_inputs = 2 + number_of_outputs = 1 + number_of_activators = 1 + input_names = list( + "L", + "H" + ) + +/obj/item/integrated_circuit/arithmetic/random/work() + if(..()) + var/result = 0 + var/datum/integrated_io/L = inputs[1] + var/datum/integrated_io/H = inputs[2] + + if(isnum(L.data) && isnum(H.data)) + result = rand(L.data, H.data) + + for(var/datum/integrated_io/output/O in outputs) + O.data = result + O.push_data() \ No newline at end of file diff --git a/code/modules/integrated_electronics/assemblies.dm b/code/modules/integrated_electronics/assemblies.dm new file mode 100644 index 0000000000..f9037e60e7 --- /dev/null +++ b/code/modules/integrated_electronics/assemblies.dm @@ -0,0 +1,168 @@ +/obj/item/device/electronic_assembly + name = "electronic assembly" + desc = "It's a case, for building electronics with." + w_class = 2 + icon = 'icons/obj/electronic_assemblies.dmi' + icon_state = "setup_small" + var/max_components = 10 + var/max_complexity = 40 + var/opened = 0 + +/obj/item/device/electronic_assembly/medium + name = "electronic mechanism" + icon_state = "setup_medium" + w_class = 3 + max_components = 20 + max_complexity = 80 + +/obj/item/device/electronic_assembly/large + name = "electronic machine" + icon_state = "setup_large" + w_class = 4 + max_components = 30 + max_complexity = 120 + +/obj/item/device/electronic_assembly/drone + name = "electronic drone" + icon_state = "setup_drone" + w_class = 3 + max_components = 25 + max_complexity = 100 + +/obj/item/device/electronic_assembly/interact(mob/user) + if(get_dist(get_turf(src), user) > 1) + user.unset_machine(src) + return + var/total_parts = 0 + var/total_complexity = 0 + for(var/obj/item/integrated_circuit/part in contents) + total_parts++ + total_complexity = total_complexity + part.complexity + var/HTML = "[src.name]" + + HTML += "
\[Refresh\] | " + HTML += "\[Rename\]
" + HTML += "[total_parts]/[max_components] ([round((total_parts / max_components) * 100, 0.1)]%) space taken up in the assembly.
" + HTML += "[total_complexity]/[max_complexity] ([round((total_complexity / max_complexity) * 100, 0.1)]%) maximum complexity." + HTML += "

" + HTML += "Components;
" + for(var/obj/item/integrated_circuit/circuit in contents) + HTML += "[circuit.name] | " + HTML += "\[Rename\]" + HTML += "
" + + HTML += "" + user << browse(HTML, "window=assembly-\ref[src];size=600x350;border=1;can_resize=1;can_close=1;can_minimize=1") + +/obj/item/device/electronic_assembly/Topic(href, href_list[]) + var/mob/living/user = locate(href_list["user"]) in mob_list + + if(..()) + return 1 + + if(!user.canmove || user.stat || user.restrained()) + return + + if(href_list["rename"]) + rename(user) + + interact(user) // To refresh the UI. + +/obj/item/device/electronic_assembly/verb/rename() + set name = "Rename Circuit" + set category = "Object" + set desc = "Rename your circuit, useful to stay organized." + + var/mob/M = usr + + if(!M.canmove || M.stat || M.restrained()) + return + + var/input = sanitizeSafe(input("What do you want to name this?", "Rename", src.name), MAX_NAME_LEN) + + if(src && input) + M << "The machine now has a label reading '[input]'." + name = input + +/obj/item/device/electronic_assembly/update_icon() + if(opened) + icon_state = initial(icon_state) + "-open" + else + icon_state = initial(icon_state) + +/obj/item/device/electronic_assembly/examine(mob/user) + ..() + if(user.Adjacent(src)) + if(!opened) + for(var/obj/item/integrated_circuit/output/screen/S in contents) + if(S.stuff_to_display) + user << "There's a little screen labeled '[S.name]', which displays '[S.stuff_to_display]'." + else + interact(user) + // var/obj/item/integrated_circuit/IC = input(user, "Which circuit do you want to examine?", "Examination") as null|anything in contents + // if(IC) + // IC.examine(user) + +/obj/item/device/electronic_assembly/attackby(var/obj/item/I, var/mob/user) + if(istype(I, /obj/item/integrated_circuit)) + if(!opened) + user << "\The [src] isn't opened, so you can't put anything inside. Try using a crowbar." + return 0 + var/obj/item/integrated_circuit/IC = I + var/total_parts = 0 + var/total_complexity = 0 + for(var/obj/item/integrated_circuit/part in contents) + total_parts++ + total_complexity = total_complexity + part.complexity + + if( (total_parts + 1) >= max_components) + user << "You can't seem to add this [IC.name], since there's no more room." + return 0 + if( (total_complexity + IC.complexity) >= max_complexity) + user << "You can't seem to add this [IC.name], since this setup's too complicated for the case." + return 0 + + user << "You slide \the [IC] inside \the [src]." + user.drop_item() + IC.forceMove(src) + playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1) + if(istype(I, /obj/item/weapon/screwdriver)) + if(!opened) + user << "\The [src] isn't opened, so you can't remove anything inside. Try using a crowbar." + return 0 + if(!contents.len) + user << "There's nothing inside this to remove!" + return 0 + var/obj/item/integrated_circuit/option = input("What do you want to remove?", "Component Removal") as null|anything in contents + if(option) + option.disconnect_all() + option.forceMove(get_turf(src)) + playsound(src.loc, 'sound/items/Crowbar.ogg', 50, 1) + user << "You pop \the [option] out of the case, and slide it out." + if(istype(I, /obj/item/weapon/crowbar)) + playsound(src.loc, 'sound/items/Crowbar.ogg', 50, 1) + opened = !opened + user << "You [opened ? "opened" : "closed"] \the [src]." + update_icon() + if(istype(I, /obj/item/device/integrated_electronics/wirer)) + if(opened) + var/obj/item/integrated_circuit/IC = input(user, "Which circuit do you want to examine?", "Examination") as null|anything in contents + if(IC) + IC.examine(user) + else + user << "\The [src] isn't opened, so you can't fiddle with the internal components. \ + Try using a crowbar." + +/obj/item/device/electronic_assembly/attack_self(mob/user) + var/list/available_inputs = list() + for(var/obj/item/integrated_circuit/input/input in contents) + if(input.can_be_asked_input) + available_inputs.Add(input) + var/obj/item/integrated_circuit/input/choice = input(user, "What do you want to interact with?", "Interaction") as null|anything in available_inputs + if(choice) + choice.ask_for_input(user) + +/obj/item/device/electronic_assembly/emp_act(severity) + ..() + for(var/atom/movable/AM in contents) + AM.emp_act(severity) diff --git a/code/modules/integrated_electronics/converters.dm b/code/modules/integrated_electronics/converters.dm new file mode 100644 index 0000000000..7a837abbfa --- /dev/null +++ b/code/modules/integrated_electronics/converters.dm @@ -0,0 +1,133 @@ +//These circuits convert one variable to another. +/obj/item/integrated_circuit/converter + complexity = 2 + number_of_inputs = 1 + number_of_outputs = 1 + number_of_activators = 1 + input_names = list( + "input", + ) + output_names = list( + "result" + ) + activator_names = list( + "convert" + ) + +/obj/item/integrated_circuit/converter/num2text + name = "number to string" + desc = "This circuit can convert a number variable into a string." + icon_state = "num-string" + +/obj/item/integrated_circuit/converter/num2text/work() + if(..()) + var/result = null + var/datum/integrated_io/incoming = inputs[1] + var/datum/integrated_io/outgoing = outputs[1] + if(incoming.data && isnum(incoming.data)) + result = num2text(incoming.data) + + outgoing.data = result + outgoing.push_data() + +/obj/item/integrated_circuit/converter/text2num + name = "string to number" + desc = "This circuit can convert a string variable into a number." + icon_state = "string-num" + +/obj/item/integrated_circuit/converter/text2num/work() + if(..()) + var/result = null + var/datum/integrated_io/incoming = inputs[1] + var/datum/integrated_io/outgoing = outputs[1] + if(incoming.data && istext(incoming.data)) + result = text2num(incoming.data) + + outgoing.data = result + outgoing.push_data() + +/obj/item/integrated_circuit/converter/ref2text + name = "reference to string" + desc = "This circuit can convert a reference to something else to a string, specifically the name of that reference." + icon_state = "ref-string" + +/obj/item/integrated_circuit/converter/ref2text/work() + if(..()) + var/result = null + var/datum/integrated_io/incoming = inputs[1] + var/datum/integrated_io/outgoing = outputs[1] + if(incoming.data && istype(incoming.data, /atom/)) + var/atom/A = incoming.data + result = A.name + + outgoing.data = result + outgoing.push_data() + +/obj/item/integrated_circuit/converter/lowercase + name = "lowercase string converter" + desc = "this will cause a string to come out in all lowercase." + icon_state = "lowercase" + +/obj/item/integrated_circuit/converter/lowercase/work() + if(..()) + var/result = null + var/datum/integrated_io/incoming = inputs[1] + var/datum/integrated_io/outgoing = outputs[1] + if(incoming.data && istext(incoming.data)) + result = lowertext(incoming.data) + + outgoing.data = result + outgoing.push_data() + +/obj/item/integrated_circuit/converter/uppercase + name = "uppercase string converter" + desc = "THIS WILL CAUSE A STRING TO COME OUT IN ALL UPPERCASE." + icon_state = "uppercase" + +/obj/item/integrated_circuit/converter/uppercase/work() + if(..()) + var/result = null + var/datum/integrated_io/incoming = inputs[1] + var/datum/integrated_io/outgoing = outputs[1] + if(incoming.data && istext(incoming.data)) + result = uppertext(incoming.data) + + outgoing.data = result + outgoing.push_data() + +/obj/item/integrated_circuit/converter/concatenatior + name = "concatenatior" + desc = "This joins many strings together to get one big string." + complexity = 4 + number_of_inputs = 8 + number_of_outputs = 1 + number_of_activators = 1 + input_names = list( + "A", + "B", + "C", + "D", + "E", + "F", + "G", + "H" + ) + output_names = list( + "result" + ) + activator_names = list( + "concatenate" + ) + + +/obj/item/integrated_circuit/converter/concatenatior/work() + if(..()) + var/result = null + for(var/datum/integrated_io/input/I in inputs) + I.pull_data() + if(istext(I.data)) + result = result + I.data + + var/datum/integrated_io/outgoing = outputs[1] + outgoing.data = result + outgoing.push_data() \ No newline at end of file diff --git a/code/modules/integrated_electronics/coordinate.dm b/code/modules/integrated_electronics/coordinate.dm new file mode 100644 index 0000000000..78b7ebcb4f --- /dev/null +++ b/code/modules/integrated_electronics/coordinate.dm @@ -0,0 +1,75 @@ +//This circuit gives information on where the machine is. +/obj/item/integrated_circuit/gps + name = "global positioning system" + desc = "This allows you to easily know the position of a machine containing this device." + icon_state = "gps" + complexity = 4 + number_of_inputs = 0 + number_of_outputs = 2 + number_of_activators = 1 + input_names = list( + ) + output_names = list( + "X (abs)", + "Y (abs)" + ) + activator_names = list( + "get coordinates" + ) + +/obj/item/integrated_circuit/gps/work() + if(..()) + var/turf/T = get_turf(src) + var/datum/integrated_io/result_x = outputs[1] + var/datum/integrated_io/result_y = outputs[2] + + result_x.data = null + result_y.data = null + if(!T) + return + + result_x.data = T.x + result_y.data = T.y + + for(var/datum/integrated_io/output/O in outputs) + O.push_data() + +/obj/item/integrated_circuit/abs_to_rel_coords + name = "abs to rel coordinate converter" + desc = "Easily convert absolute coordinates to relative coordinates with this." + complexity = 4 + number_of_inputs = 4 + number_of_outputs = 2 + number_of_activators = 1 + input_names = list( + "X1 (abs)", + "Y1 (abs)", + "X2 (abs)", + "Y2 (abs)" + ) + output_names = list( + "X (rel)", + "Y (rel)" + ) + activator_names = list( + "compute rel coordinates" + ) + +/obj/item/integrated_circuit/abs_to_rel_coords/work() + var/datum/integrated_io/x1 = inputs[1] + var/datum/integrated_io/y1 = inputs[2] + + var/datum/integrated_io/x2 = inputs[3] + var/datum/integrated_io/y2 = inputs[4] + + var/datum/integrated_io/result_x = outputs[1] + var/datum/integrated_io/result_y = outputs[2] + + if(x1.data && y1.data && x2.data && y2.data) + result_x.data = x1.data - x2.data + result_y.data = y1.data - y2.data + + + for(var/datum/integrated_io/output/O in outputs) + O.push_data() + ..() diff --git a/code/modules/integrated_electronics/data_transfer.dm b/code/modules/integrated_electronics/data_transfer.dm new file mode 100644 index 0000000000..12380e9cca --- /dev/null +++ b/code/modules/integrated_electronics/data_transfer.dm @@ -0,0 +1,79 @@ +/obj/item/integrated_circuit/transfer/splitter + name = "splitter" + desc = "Splits incoming data into all of the output pins." + icon_state = "splitter" + complexity = 3 + number_of_inputs = 1 + number_of_outputs = 2 + input_names = list( + "data to split" + ) + output_names = list( + "A", + "B", + "C", + "D", + "E", + "F", + "G", + "H" + ) + +/obj/item/integrated_circuit/transfer/splitter/medium + name = "four splitter" + icon_state = "splitter4" + complexity = 5 + number_of_inputs = 1 + number_of_outputs = 4 + +/obj/item/integrated_circuit/transfer/splitter/large + name = "eight splitter" + icon_state = "splitter8" + complexity = 9 + number_of_inputs = 1 + number_of_outputs = 8 + +/obj/item/integrated_circuit/transfer/splitter/work() + if(..()) + var/datum/integrated_io/I = inputs[1] + for(var/datum/integrated_io/output/O in outputs) + O.data = I.data + +/obj/item/integrated_circuit/transfer/activator_splitter + name = "activator splitter" + desc = "Splits incoming activation pulses into all of the output pins." + icon_state = "splitter" + complexity = 3 + number_of_activators = 3 + activator_names = list( + "incoming pulse", + "outgoing pulse A", + "outgoing pulse B", + "outgoing pulse C", + "outgoing pulse D", + "outgoing pulse E", + "outgoing pulse F", + "outgoing pulse G", + "outgoing pulse H" + ) + +/obj/item/integrated_circuit/transfer/activator_splitter/work() + if(..()) + for(var/datum/integrated_io/activate/A in outputs) + if(A == activators[1]) + continue + if(A.linked.len) + for(var/datum/integrated_io/activate/target in A.linked) + target.holder.work() + +/obj/item/integrated_circuit/transfer/activator_splitter/medium + name = "four activator splitter" + icon_state = "splitter4" + complexity = 5 + number_of_activators = 5 + +/obj/item/integrated_circuit/transfer/activator_splitter/large + name = "eight activator splitter" + icon_state = "splitter4" + complexity = 9 + number_of_activators = 9 diff --git a/code/modules/integrated_electronics/input_output.dm b/code/modules/integrated_electronics/input_output.dm new file mode 100644 index 0000000000..42da340654 --- /dev/null +++ b/code/modules/integrated_electronics/input_output.dm @@ -0,0 +1,494 @@ +/obj/item/integrated_circuit/input + var/can_be_asked_input = 0 + +/obj/item/integrated_circuit/input/proc/ask_for_input(mob/user) + return + +/obj/item/integrated_circuit/input/button + name = "button" + desc = "This tiny button must do something, right?" + icon_state = "button" + number_of_inputs = 0 + number_of_outputs = 0 + number_of_activators = 1 + complexity = 1 + can_be_asked_input = 1 + activator_names = list( + "on pressed" + ) + +/obj/item/integrated_circuit/input/button/ask_for_input(mob/user) //Bit misleading name for this specific use. + var/datum/integrated_io/A = activators[1] + if(A.linked.len) + for(var/datum/integrated_io/activate/target in A.linked) + target.holder.work() + user << "You press the button labeled '[src.name]'." + +/obj/item/integrated_circuit/input/numberpad + name = "number pad" + desc = "This small number pad allows someone to input a number into the system." + icon_state = "numberpad" + number_of_inputs = 0 + number_of_outputs = 1 + number_of_activators = 1 + complexity = 2 + can_be_asked_input = 1 + output_names = list( + "number entered" + ) + activator_names = list( + "on entered" + ) + +/obj/item/integrated_circuit/input/numberpad/ask_for_input(mob/user) + var/new_input = input(user, "Enter a number, please.","Number pad") as null|num + if(isnum(new_input)) + var/datum/integrated_io/O = outputs[1] + O.data = new_input + O.push_data() + var/datum/integrated_io/A = activators[1] + A.push_data() + +/obj/item/integrated_circuit/input/textpad + name = "text pad" + desc = "This small text pad allows someone to input a string into the system." + icon_state = "textpad" + number_of_inputs = 0 + number_of_outputs = 1 + number_of_activators = 1 + complexity = 2 + can_be_asked_input = 1 + output_names = list( + "string entered" + ) + activator_names = list( + "on entered" + ) + +/obj/item/integrated_circuit/input/textpad/ask_for_input(mob/user) + var/new_input = input(user, "Enter some words, please.","Number pad") as null|text + if(new_input && istext(new_input)) + var/datum/integrated_io/O = outputs[1] + O.data = new_input + O.push_data() + var/datum/integrated_io/A = activators[1] + A.push_data() + +/obj/item/integrated_circuit/input/med_scanner + name = "integrated medical analyser" + desc = "A very small version of the common medical analyser. This allows the machine to know how healthy someone is." + icon_state = "medscan" + number_of_inputs = 1 + number_of_outputs = 2 + number_of_activators = 1 + complexity = 4 + input_names = list( + "target ref" + ) + output_names = list( + "total health %", + "total missing health" + ) + activator_names = list( + "scan" + ) + +/obj/item/integrated_circuit/input/med_scanner/work() + if(..()) + var/datum/integrated_io/I = inputs[1] + if(!I.data || !ishuman(I.data)) //Invalid input + return + var/mob/living/carbon/human/H = I.data + if(H.Adjacent(get_turf(src))) // Like normal analysers, it can't be used at range. + var/total_health = round(H.health/H.maxHealth, 0.1)*100 + var/missing_health = H.maxHealth - H.health + + var/datum/integrated_io/total = outputs[1] + var/datum/integrated_io/missing = outputs[2] + + total.data = total_health + missing.data = missing_health + + for(var/datum/integrated_io/output/O in outputs) + O.push_data() + +/obj/item/integrated_circuit/input/adv_med_scanner + name = "integrated advanced medical analyser" + desc = "A very small version of the common medical analyser. This allows the machine to know how healthy someone is. \ + This type is much more precise, allowing the machine to know much more about the target than a normal analyzer." + icon_state = "medscan_adv" + number_of_inputs = 1 + number_of_outputs = 7 + number_of_activators = 1 + complexity = 12 + input_names = list( + "target ref" + ) + output_names = list( + "total health %", + "total missing health", + "brute damage", + "burn damage", + "tox damage", + "oxy damage", + "clone damage" + ) + activator_names = list( + "scan" + ) + +/obj/item/integrated_circuit/input/adv_med_scanner/work() + if(..()) + var/datum/integrated_io/I = inputs[1] + if(!I.data || !ishuman(I.data)) //Invalid input + return + var/mob/living/carbon/human/H = I.data + if(H.Adjacent(get_turf(src))) // Like normal analysers, it can't be used at range. + var/total_health = round(H.health/H.maxHealth, 0.1)*100 + var/missing_health = H.maxHealth - H.health + + var/datum/integrated_io/total = outputs[1] + var/datum/integrated_io/missing = outputs[2] + var/datum/integrated_io/brute = outputs[3] + var/datum/integrated_io/burn = outputs[4] + var/datum/integrated_io/tox = outputs[5] + var/datum/integrated_io/oxy = outputs[6] + var/datum/integrated_io/clone = outputs[7] + + total.data = total_health + missing.data = missing_health + brute.data = H.getBruteLoss() + burn.data = H.getFireLoss() + tox.data = H.getToxLoss() + oxy.data = H.getOxyLoss() + clone.data = H.getCloneLoss() + + for(var/datum/integrated_io/output/O in outputs) + O.push_data() + +/obj/item/integrated_circuit/input/local_locator + name = "local locator" + desc = "This is needed for certain devices that demand a reference for a target to act upon. This type only locates something \ + that is holding the machine containing it." + number_of_inputs = 0 + number_of_outputs = 1 + number_of_activators = 1 + complexity = 4 + output_names = list( + "located ref" + ) + activator_names = list( + "locate" + ) + +/obj/item/integrated_circuit/input/local_locator/work() + if(..()) + var/mob/living/L = null + var/datum/integrated_io/O = outputs[1] + O.data = null + if(istype(src.loc, /obj/item/device/electronic_assembly)) // Check to make sure we're actually in a machine. + var/obj/item/device/electronic_assembly/assembly = src.loc + if(istype(assembly.loc, /mob/living)) // Now check if someone's holding us. + L = assembly.loc + + if(L) + O.data = L + + O.push_data() + +/obj/item/integrated_circuit/input/signaler + name = "integrated signaler" + desc = "Signals from a signaler can be received with this, allowing for remote control. Additionally, it can send signals as well." + extended_desc = "When a signal is received from another signaler, the 'on signal received' activator pin will be pulsed. \ + The two input pins are to configure the integrated signaler's settings. Note that the frequency should not have a decimal in it. \ + Meaning the default frequency is expressed as 1457, not 145.7. To send a signal, pulse the 'send signal' activator pin." + icon_state = "signal" + number_of_inputs = 2 + number_of_outputs = 0 + number_of_activators = 2 + complexity = 4 + input_names = list( + "frequency", + "code" + ) + activator_names = list( + "send signal", + "on signal received" + ) + var/frequency = 1457 + var/code = 30 + var/datum/radio_frequency/radio_connection + +/obj/item/integrated_circuit/input/signaler/New() + ..() + spawn(4 SECONDS) + set_frequency(frequency) + var/datum/integrated_io/new_freq = inputs[1] + var/datum/integrated_io/new_code = inputs[2] + // Set the pins so when someone sees them, they won't show as null + new_freq.data = frequency + new_code.data = code + +/obj/item/integrated_circuit/input/signaler/Destroy() + if(radio_controller) + radio_controller.remove_object(src,frequency) + frequency = 0 + ..() + +/obj/item/integrated_circuit/input/signaler/on_data_written() + var/datum/integrated_io/new_freq = inputs[1] + var/datum/integrated_io/new_code = inputs[2] + if(isnum(new_freq.data)) + set_frequency(new_freq.data) + if(isnum(new_code.data)) + code = new_code.data + + +/obj/item/integrated_circuit/input/signaler/work() // Sends a signal. + if(..()) + if(!radio_connection) + return + + var/datum/signal/signal = new() + signal.source = src + signal.encryption = code + signal.data["message"] = "ACTIVATE" + radio_connection.post_signal(src, signal) + +/obj/item/integrated_circuit/input/signaler/proc/set_frequency(new_frequency) + if(!frequency) + return + if(!radio_controller) + sleep(20) + if(!radio_controller) + return + radio_controller.remove_object(src, frequency) + frequency = new_frequency + radio_connection = radio_controller.add_object(src, frequency, RADIO_CHAT) + +/obj/item/integrated_circuit/input/signaler/receive_signal(datum/signal/signal) + var/datum/integrated_io/new_code = inputs[2] + var/code = 0 + + if(isnum(new_code.data)) + code = new_code.data + if(!signal) + return 0 + if(signal.encryption != code) + return 0 + if(signal.source == src) // Don't trigger ourselves. + return 0 + + var/datum/integrated_io/A = activators[2] + A.push_data() + + for(var/mob/O in hearers(1, src.loc)) + O.show_message(text("\icon[] *beep* *beep*", src), 3, "*beep* *beep*", 2) + + +/obj/item/integrated_circuit/input/EPv2 + name = "\improper EPv2 circuit" + desc = "Enables the sending and receiving of messages on the Exonet with the EPv2 protocol." + extended_desc = "An EPv2 address is a string with the format of XXXX:XXXX:XXXX:XXXX. Data can be send or received using the \ + second pin on each side, with additonal data reserved for the third pin. When a message is received, the second activaiton pin \ + will pulse whatever's connected to it. Pulsing the first activation pin will send a message." + icon_state = "signal" + number_of_inputs = 3 + number_of_outputs = 3 + number_of_activators = 2 + complexity = 4 + input_names = list( + "target EPv2 address", + "data to send", + "secondary text" + ) + output_names = list( + "address received", + "data received", + "secondary text received" + ) + activator_names = list( + "send data", + "on data received" + ) + var/datum/exonet_protocol/exonet = null + +/obj/item/integrated_circuit/input/EPv2/New() + ..() + exonet = new(src) + exonet.make_address("EPv2_circuit-\ref[src]") + desc += "This circuit's EPv2 address is: [exonet.address]." + +/obj/item/integrated_circuit/input/EPv2/Destroy() + if(exonet) + exonet.remove_address() + qdel(exonet) + ..() + +/obj/item/integrated_circuit/input/EPv2/work() + if(..()) + var/datum/integrated_io/target_address = inputs[1] + var/datum/integrated_io/message = inputs[2] + var/datum/integrated_io/text = inputs[3] + if(istext(target_address.data)) + exonet.send_message(target_address.data, message.data, text.data) + +/obj/item/integrated_circuit/input/receive_exonet_message(var/atom/origin_atom, var/origin_address, var/message, var/text) + var/datum/integrated_io/message_received = outputs[1] + var/datum/integrated_io/data_received = outputs[2] + var/datum/integrated_io/text_received = outputs[3] + + var/datum/integrated_io/A = activators[2] + A.push_data() + + message_received.write_data_to_pin(origin_address) + data_received.write_data_to_pin(message) + text_received.write_data_to_pin(text) + +/obj/item/integrated_circuit/output/screen + name = "screen" + desc = "This small screen can display a single piece of data, when the machine is examined closely." + icon_state = "screen" + complexity = 4 + number_of_inputs = 1 + number_of_outputs = 0 + number_of_activators = 1 + input_names = list( + "displayed data" + ) + activator_names = list( + "load data" + ) + var/stuff_to_display = null + +/obj/item/integrated_circuit/output/screen/work() + var/datum/integrated_io/I = inputs[1] + stuff_to_display = I.data + +/obj/item/integrated_circuit/output/light + name = "light" + desc = "This light can turn on and off on command." + icon_state = "light_adv" +// icon_state = "light" + complexity = 4 + number_of_inputs = 0 + number_of_outputs = 0 + number_of_activators = 1 + activator_names = list( + "toggle light" + ) + var/light_toggled = 0 + var/light_brightness = 3 + var/light_rgb = "#FFFFFF" + +/obj/item/integrated_circuit/output/light/work() + if(..()) + light_toggled = !light_toggled + update_lighting() + +/obj/item/integrated_circuit/output/light/proc/update_lighting() + if(light_toggled) + set_light(l_range = light_brightness, l_power = light_brightness, l_color = light_rgb) + else + set_light(0) + +/obj/item/integrated_circuit/output/light/advanced/update_lighting() + var/datum/integrated_io/R = inputs[1] + var/datum/integrated_io/G = inputs[2] + var/datum/integrated_io/B = inputs[3] + var/datum/integrated_io/brightness = inputs[4] + + if(isnum(R.data) && isnum(G.data) && isnum(B.data) && isnum(brightness.data)) + R.data = Clamp(R.data, 0, 255) + G.data = Clamp(G.data, 0, 255) + B.data = Clamp(B.data, 0, 255) + brightness.data = Clamp(brightness.data, 0, 6) + light_rgb = rgb(R.data, G.data, B.data) + light_brightness = brightness.data + + ..() + +/obj/item/integrated_circuit/output/light/advanced + name = "advanced light" + desc = "This light can turn on and off on command, in any color, and in various brightness levels." + icon_state = "light_adv" + complexity = 8 + number_of_inputs = 4 + number_of_outputs = 0 + number_of_activators = 1 + input_names = list( + "R", + "G", + "B", + "Brightness" + ) + +/obj/item/integrated_circuit/output/light/advanced/on_data_written() + update_lighting() + +/obj/item/integrated_circuit/output/sound + name = "speaker circuit" + desc = "A miniature speaker is attached to this component." + icon_state = "speaker" + complexity = 8 + cooldown_per_use = 4 SECONDS + number_of_inputs = 3 + number_of_outputs = 0 + number_of_activators = 1 + input_names = list( + "sound ID", + "volume", + "frequency" + ) + activator_names = list( + "play sound" + ) + var/list/sounds = list() + +/obj/item/integrated_circuit/output/sound/work() + if(..()) + var/datum/integrated_io/ID = inputs[1] + var/datum/integrated_io/vol = inputs[2] + var/datum/integrated_io/frequency = inputs[3] + if(istext(ID.data) && isnum(vol.data) && isnum(frequency.data)) + var/selected_sound = sounds[ID.data] + vol.data = Clamp(vol.data, 0, 1) + frequency.data = Clamp(frequency.data, 0, 100) + playsound(get_turf(src), selected_sound, vol.data, frequency.data, -1) + +/obj/item/integrated_circuit/output/sound/beeper + name = "beeper circuit" + desc = "A miniature speaker is attached to this component. This is often used in the construction of motherboards, which use \ + the speaker to tell the user if something goes very wrong when booting up. It can also do other similar synthetic sounds such \ + as buzzing, pinging, chiming, and more." + extended_desc = "The first input pin determines what sound is used. The choices are; beep, chime, buzz sigh, buzz twice, ping, \ + synth yes, synth no, warning buzz. The second pin determines the volume of sound that is played, and the third determines if \ + the frequency of the sound will vary with each activation." + sounds = list( + "beep" = 'sound/machines/twobeep.ogg', + "chime" = 'sound/machines/chime.ogg', + "buzz sigh" = 'sound/machines/buzz-sigh.ogg', + "buzz twice" = 'sound/machines/buzz-two.ogg', + "ping" = 'sound/machines/ping.ogg', + "synth yes" = 'sound/machines/synth_yes.ogg', + "synth no" = 'sound/machines/synth_no.ogg', + "warning buzz" = 'sound/machines/warning-buzzer.ogg' + ) + +/obj/item/integrated_circuit/output/sound/beepsky + name = "securitron sound circuit" + desc = "A miniature speaker is attached to this component. Considered by some to be the essential component for a securitron." + extended_desc = "The first input pin determines what sound is used. The choices are; creep, criminal, freeze, god, \ + i am the law, insult, radio, secure day. The second pin determines the volume of sound that is played, and the \ + third determines if the frequency of the sound will vary with each activation." + sounds = list( + "creep" = 'sound/voice/bcreep.ogg', + "criminal" = 'sound/voice/bcriminal.ogg', + "freeze" = 'sound/voice/bfreeze.ogg', + "god" = 'sound/voice/bgod.ogg', + "i am the law" = 'sound/voice/biamthelaw.ogg', + "insult" = 'sound/voice/binsult.ogg', + "radio" = 'sound/voice/bradio.ogg', + "secure day" = 'sound/voice/bsecureday.ogg', + ) + diff --git a/code/modules/integrated_electronics/logic.dm b/code/modules/integrated_electronics/logic.dm new file mode 100644 index 0000000000..4d123c61d0 --- /dev/null +++ b/code/modules/integrated_electronics/logic.dm @@ -0,0 +1,172 @@ +/obj/item/integrated_circuit/logic + name = "logic gate" + desc = "This tiny chip will decide for you!" + complexity = 3 + number_of_inputs = 2 + number_of_outputs = 1 + number_of_activators = 2 + input_names = list( + "A", + "B" + ) + output_names = list( + "result" + ) + activator_names = list( + "compare", + "on true result" + ) + +/obj/item/integrated_circuit/logic/equals + name = "equal gate" + desc = "This gate compares two values, and outputs the number one if both are the same." + icon_state = "equal" + +/obj/item/integrated_circuit/logic/equals/work() + if(..()) + var/datum/integrated_io/A = inputs[1] + var/datum/integrated_io/B = inputs[2] + var/datum/integrated_io/O = outputs[1] + var/datum/integrated_io/P = activators[2] + if(A.data == B.data) + O.data = 1 + O.push_data() + P.push_data() + else + O.data = 0 + +/obj/item/integrated_circuit/logic/not + name = "not gate" + desc = "This gate inverts what's fed into it." + icon_state = "not" + number_of_inputs = 1 + number_of_outputs = 1 + number_of_activators = 1 + output_names = list( + "invert" + ) + + +/obj/item/integrated_circuit/logic/not/work() + if(..()) + var/datum/integrated_io/A = inputs[1] + var/datum/integrated_io/O = outputs[1] + if(A.data) + O.data = !A.data + O.push_data() + else + O.data = 0 + +/obj/item/integrated_circuit/logic/and + name = "and gate" + desc = "This gate will output 'one' if both inputs evaluate to true." + icon_state = "and" + +/obj/item/integrated_circuit/logic/and/work() + if(..()) + var/datum/integrated_io/A = inputs[1] + var/datum/integrated_io/B = inputs[2] + var/datum/integrated_io/O = outputs[1] + var/datum/integrated_io/P = activators[2] + if(A.data && B.data) + O.data = 1 + O.push_data() + A.push_data() + P.push_data() + else + O.data = 0 + +/obj/item/integrated_circuit/logic/or + name = "or gate" + desc = "This gate will output 'one' if one of the inputs evaluate to true." + icon_state = "or" + +/obj/item/integrated_circuit/logic/or/work() + if(..()) + var/datum/integrated_io/A = inputs[1] + var/datum/integrated_io/B = inputs[2] + var/datum/integrated_io/O = outputs[1] + var/datum/integrated_io/P = activators[2] + if(A.data || B.data) + O.data = 1 + O.push_data() + A.push_data() + P.push_data() + else + O.data = 0 + +/obj/item/integrated_circuit/logic/less_than + name = "less than gate" + desc = "This will output 'one' if the first input is less than the second input." + icon_state = "less_than" + +/obj/item/integrated_circuit/logic/less_than/work() + if(..()) + var/datum/integrated_io/A = inputs[1] + var/datum/integrated_io/B = inputs[2] + var/datum/integrated_io/O = outputs[1] + var/datum/integrated_io/P = activators[2] + if(A.data < B.data) + O.data = 1 + O.push_data() + A.push_data() + P.push_data() + else + O.data = 0 + +/obj/item/integrated_circuit/logic/less_than_or_equal + name = "less than or equal gate" + desc = "This will output 'one' if the first input is less than, or equal to the second input." + icon_state = "less_than_or_equal" + +/obj/item/integrated_circuit/logic/less_than_or_equal/work() + if(..()) + var/datum/integrated_io/A = inputs[1] + var/datum/integrated_io/B = inputs[2] + var/datum/integrated_io/O = outputs[1] + var/datum/integrated_io/P = activators[2] + if(A.data <= B.data) + O.data = 1 + O.push_data() + A.push_data() + P.push_data() + else + O.data = 0 + +/obj/item/integrated_circuit/logic/greater_than + name = "greater than gate" + desc = "This will output 'one' if the first input is greater than the second input." + icon_state = "greater_than" + +/obj/item/integrated_circuit/logic/greater_than/work() + if(..()) + var/datum/integrated_io/A = inputs[1] + var/datum/integrated_io/B = inputs[2] + var/datum/integrated_io/O = outputs[1] + var/datum/integrated_io/P = activators[2] + if(A.data > B.data) + O.data = 1 + O.push_data() + A.push_data() + P.push_data() + else + O.data = 0 + +/obj/item/integrated_circuit/logic/greater_than_or_equal + name = "greater_than or equal gate" + desc = "This will output 'one' if the first input is greater than, or equal to the second input." + icon_state = "greater_than_or_equal" + +/obj/item/integrated_circuit/logic/greater_than_or_equal/work() + if(..()) + var/datum/integrated_io/A = inputs[1] + var/datum/integrated_io/B = inputs[2] + var/datum/integrated_io/O = outputs[1] + var/datum/integrated_io/P = activators[2] + if(A.data >= B.data) + O.data = 1 + O.push_data() + A.push_data() + P.push_data() + else + O.data = 0 \ No newline at end of file diff --git a/code/modules/integrated_electronics/manipulation.dm b/code/modules/integrated_electronics/manipulation.dm new file mode 100644 index 0000000000..256d7b6b7a --- /dev/null +++ b/code/modules/integrated_electronics/manipulation.dm @@ -0,0 +1,158 @@ +/obj/item/integrated_circuit/manipulation/weapon_firing + name = "weapon firing mechanism" + desc = "This somewhat complicated system allows one to slot in a gun, direct it towards a position, and remotely fire it." + extended_desc = "The firing mechanism can slot in most ranged weapons, ballistic and energy. \ + The first and second inputs need to be numbers. They are coordinates for the gun to fire at, relative to the machine itself. \ + The 'fire' activator will cause the mechanism to attempt to fire the weapon at the coordinates, if possible. Note that the \ + normal limitations to firearms, such as ammunition requirements and firing delays, still hold true if fired by the mechanism." + complexity = 20 + number_of_inputs = 2 + number_of_outputs = 0 + number_of_activators = 1 + input_names = list( + "target X rel", + "target Y rel" + ) + activator_names = list( + "fire" + ) + var/obj/item/weapon/gun/installed_gun = null + +/obj/item/integrated_circuit/manipulation/weapon_firing/Destroy() + qdel(installed_gun) + ..() + +/obj/item/integrated_circuit/manipulation/weapon_firing/attackby(var/obj/O, var/mob/user) + if(istype(O, /obj/item/weapon/gun)) + var/obj/item/weapon/gun/gun = O + if(installed_gun) + user << "There's already a weapon installed." + return + user.drop_from_inventory(gun) + installed_gun = gun + gun.forceMove(src) + user << "You slide \the [gun] into the firing mechanism." + playsound(src.loc, 'sound/items/Crowbar.ogg', 50, 1) + else + ..() + +/obj/item/integrated_circuit/manipulation/weapon_firing/attack_self(var/mob/user) + if(installed_gun) + installed_gun.forceMove(get_turf(src)) + user << "You slide \the [installed_gun] out of the firing mechanism." + playsound(src.loc, 'sound/items/Crowbar.ogg', 50, 1) + installed_gun = null + else + user << "There's no weapon to remove from the mechanism." + +/obj/item/integrated_circuit/manipulation/weapon_firing/work() + if(..()) + if(!installed_gun) + return + + var/datum/integrated_io/target_x = inputs[1] + var/datum/integrated_io/target_y = inputs[2] + + if(target_x.data && target_y.data && isnum(target_x.data) && isnum(target_y.data)) + var/turf/T = get_turf(src) + + if(target_x.data == 0 && target_y.data == 0) // Don't shoot ourselves. + return + + // We need to do this in order to enable relative coordinates, as locate() only works for absolute coordinates. + var/i + if(target_x.data > 0) + i = abs(target_x.data) + while(i) + T = get_step(T, EAST) + i-- + else if(target_x.data < 0) + i = abs(target_x.data) + while(i) + T = get_step(T, WEST) + i-- + + if(target_y.data > 0) + i = abs(target_y.data) + while(i) + T = get_step(T, NORTH) + i-- + else if(target_y.data < 0) + i = abs(target_y.data) + while(i) + T = get_step(T, SOUTH) + i-- + + if(!T) + return + installed_gun.Fire_userless(T) + +/obj/item/integrated_circuit/manipulation/smoke + name = "smoke generator" + desc = "Unlike most electronics, creating smoke is completely intentional." + icon_state = "smoke" + extended_desc = "This smoke generator creates clouds of smoke on command. It can also hold liquids inside, which will go \ + into the smoke clouds when activated." + flags = OPENCONTAINER + complexity = 20 + number_of_inputs = 0 + number_of_outputs = 0 + number_of_activators = 1 + cooldown_per_use = 30 SECONDS + input_names = list() + activator_names = list( + "create smoke" + ) + +/obj/item/integrated_circuit/manipulation/smoke/New() + ..() + create_reagents(100) + +/obj/item/integrated_circuit/manipulation/smoke/work() + if(..()) + playsound(src.loc, 'sound/effects/smoke.ogg', 50, 1, -3) + var/datum/effect/effect/system/smoke_spread/chem/smoke_system = new() + smoke_system.set_up(reagents, 10, 0, get_turf(src)) + spawn(0) + for(var/i = 1 to 8) + smoke_system.start() + reagents.clear_reagents() + +/obj/item/integrated_circuit/manipulation/locomotion + name = "locomotion circuit" + desc = "This allows a machine to move in a given direction." + icon_state = "locomotion" + extended_desc = "The circuit accepts a number as a direction to move towards.
\ + North/Fore = 1,
\ + South/Aft = 2,
\ + East/Starboard = 4,
\ + West/Port = 8,
\ + Northeast = 5,
\ + Northwest = 9,
\ + Southeast = 6,
\ + Southwest = 10
\ +
\ + Pulsing the 'step towards dir' activator pin will cause the machine to move a meter in that direction, assuming it is not \ + being held, or anchored in some way." + complexity = 20 + number_of_inputs = 1 + number_of_outputs = 0 + number_of_activators = 1 + input_names = list( + "dir num" + ) + activator_names = list( + "step towards dir" + ) + +/obj/item/integrated_circuit/manipulation/locomotion/work() + if(..()) + var/turf/T = get_turf(src) + if(istype(loc, /obj/item/device/electronic_assembly)) + var/obj/item/device/electronic_assembly/machine = loc + if(machine.anchored || machine.w_class >= 4) + return + if(machine.loc && machine.loc == T) // Check if we're held by someone. If the loc is the floor, we're not held. + var/datum/integrated_io/wanted_dir = inputs[1] + if(isnum(wanted_dir.data)) + step(machine, wanted_dir.data) \ No newline at end of file diff --git a/code/modules/integrated_electronics/memory.dm b/code/modules/integrated_electronics/memory.dm new file mode 100644 index 0000000000..8599cc2aed --- /dev/null +++ b/code/modules/integrated_electronics/memory.dm @@ -0,0 +1,101 @@ +/obj/item/integrated_circuit/memory + name = "memory chip" + desc = "This tiny chip can store one piece of data." + icon_state = "memory" + complexity = 1 + number_of_inputs = 1 + number_of_outputs = 1 + number_of_activators = 1 + activator_names = list( + "set" + ) + +/obj/item/integrated_circuit/memory/examine(mob/user) + ..() + var/i + for(i = 1, i <= outputs.len, i++) + var/datum/integrated_io/O = outputs[i] + user << "\The [src] has [O.data ? "'O.data'" : "nothing"] saved to address [i]." + +/obj/item/integrated_circuit/memory/work() + if(..()) + var/i + for(i = 1, i <= inputs.len, i++) + var/datum/integrated_io/I = inputs[i] + var/datum/integrated_io/O = outputs[i] + O.data = I.data + +/obj/item/integrated_circuit/memory/medium + name = "memory circuit" + desc = "This circuit can store four pieces of data." + icon_state = "memory4" + complexity = 4 + number_of_inputs = 4 + number_of_outputs = 4 + +/obj/item/integrated_circuit/memory/large + name = "large memory circuit" + desc = "This big circuit can hold eight pieces of data." + icon_state = "memory8" + complexity = 8 + number_of_inputs = 8 + number_of_outputs = 8 + +/obj/item/integrated_circuit/memory/huge + name = "large memory stick" + desc = "This stick of memory can hold up up to sixteen pieces of data." + icon_state = "memory16" + complexity = 16 + number_of_inputs = 16 + number_of_outputs = 16 + +/obj/item/integrated_circuit/memory/constant + name = "constant chip" + desc = "This tiny chip can store one piece of data, which cannot be overwritten without disassembly." + icon_state = "memory" + complexity = 1 + number_of_inputs = 0 + number_of_outputs = 1 + number_of_activators = 1 + activator_names = list( + "push data" + ) + var/accepting_refs = 0 + +/obj/item/integrated_circuit/memory/constant/work() + var/datum/integrated_io/O = outputs[1] + O.push_data() + +/obj/item/integrated_circuit/memory/constant/attack_self(mob/user) + var/datum/integrated_io/O = outputs[1] + var/type_to_use = input("Please choose a type to use.","[src] type setting") as null|anything in list("string","number","ref", "null") + var/new_data = null + switch(type_to_use) + if("string") + accepting_refs = 0 + new_data = input("Now type in a string.","[src] string writing") as null|text + if(istext(new_data)) + O.data = new_data + user << "You set \the [src]'s memory to [O.display_data()]." + if("number") + accepting_refs = 0 + new_data = input("Now type in a number.","[src] number writing") as null|num + if(isnum(new_data)) + O.data = new_data + user << "You set \the [src]'s memory to [O.display_data()]." + if("ref") + accepting_refs = 1 + user << "You turn \the [src]'s ref scanner on. Slide it across \ + an object for a ref of that object to save it in memory." + if("null") + O.data = null + user << "You set \the [src]'s memory to absolutely nothing." + +/obj/item/integrated_circuit/memory/constant/afterattack(atom/target, mob/living/user, proximity) + if(accepting_refs && proximity) + var/datum/integrated_io/O = outputs[1] + O.data = target + visible_message("[user] slides \a [src]'s over \the [target].") + user << "You set \the [src]'s memory to a reference to [O.display_data()]. The ref scanner is \ + now off." + accepting_refs = 0 \ No newline at end of file diff --git a/code/modules/integrated_electronics/time.dm b/code/modules/integrated_electronics/time.dm new file mode 100644 index 0000000000..95b8e02c46 --- /dev/null +++ b/code/modules/integrated_electronics/time.dm @@ -0,0 +1,144 @@ +/obj/item/integrated_circuit/time + name = "time circuit" + desc = "Now you can build your own clock!" + complexity = 2 + number_of_inputs = 0 + number_of_outputs = 0 + +/obj/item/integrated_circuit/time/delay + name = "two-sec delay circuit" + desc = "This sends a pulse signal out after a delay, critical for ensuring proper control flow in a complex machine. \ + This circuit is set to send a pulse after a delay of two seconds." + icon_state = "delay-20" + number_of_activators = 2 + var/delay = 20 + activator_names = list( + "incoming pulse", + "outgoing pulse" + ) + +/obj/item/integrated_circuit/time/delay/work() + if(..()) + var/datum/integrated_io/out_pulse = activators[2] + sleep(delay) + out_pulse.push_data() + +/obj/item/integrated_circuit/time/delay/five_sec + name = "five-sec delay circuit" + desc = "This sends a pulse signal out after a delay, critical for ensuring proper control flow in a complex machine. \ + This circuit is set to send a pulse after a delay of five seconds." + icon_state = "delay-50" + delay = 50 + +/obj/item/integrated_circuit/time/delay/one_sec + name = "one-sec delay circuit" + desc = "This sends a pulse signal out after a delay, critical for ensuring proper control flow in a complex machine. \ + This circuit is set to send a pulse after a delay of one second." + icon_state = "delay-10" + delay = 10 + +/obj/item/integrated_circuit/time/delay/half_sec + name = "half-sec delay circuit" + desc = "This sends a pulse signal out after a delay, critical for ensuring proper control flow in a complex machine. \ + This circuit is set to send a pulse after a delay of half a second." + icon_state = "delay-5" + delay = 5 + +/obj/item/integrated_circuit/time/delay/tenth_sec + name = "tenth-sec delay circuit" + desc = "This sends a pulse signal out after a delay, critical for ensuring proper control flow in a complex machine. \ + This circuit is set to send a pulse after a delay of 1/10th of a second." + icon_state = "delay-1" + delay = 1 + +/obj/item/integrated_circuit/time/delay/custom + name = "custom delay circuit" + desc = "This sends a pulse signal out after a delay, critical for ensuring proper control flow in a complex machine. \ + This circuit's delay can be customized, between 1/10th of a second to one hour. The delay is updated upon receiving a pulse." + icon_state = "delay" + number_of_inputs = 1 + input_names = list( + "delay time", + ) + +/obj/item/integrated_circuit/time/delay/custom/work() + var/datum/integrated_io/delay_input = inputs[1] + if(delay_input.data && isnum(delay_input.data) ) + var/new_delay = min(delay_input.data, 1) + new_delay = max(new_delay, 36000) //An hour. + delay = new_delay + + ..() + +/obj/item/integrated_circuit/time/ticker + name = "ticker circuit" + desc = "This circuit sends an automatic pulse every four seconds." + icon_state = "tick-m" + complexity = 8 + number_of_inputs = 1 + number_of_activators = 1 + var/ticks_to_pulse = 2 + var/ticks_completed = 0 + input_names = list( + "toggle ticking" + ) + activator_names = list( + "outgoing pulse" + ) + +/obj/item/integrated_circuit/time/ticker/New() + ..() + processing_objects |= src + +/obj/item/integrated_circuit/time/ticker/Destroy() + processing_objects -= src + +/obj/item/integrated_circuit/time/ticker/process() + ticks_completed++ + if( (ticks_completed % ticks_to_pulse) == 0) + var/datum/integrated_io/pulser = activators[1] + pulser.push_data() + +/obj/item/integrated_circuit/time/ticker/fast + name = "fast ticker" + desc = "This advanced circuit sends an automatic pulse every two seconds." + icon_state = "tick-f" + complexity = 12 + ticks_to_pulse = 1 + +/obj/item/integrated_circuit/time/ticker/slow + name = "slow ticker" + desc = "This simple circuit sends an automatic pulse every six seconds." + icon_state = "tick-s" + complexity = 4 + ticks_to_pulse = 3 + + +/obj/item/integrated_circuit/time/clock + name = "integrated clock" + desc = "Tells you what the local time is, specific to your station or planet." + icon_state = "clock" + number_of_inputs = 0 + number_of_outputs = 4 + number_of_activators = 1 + output_names = list( + "time (string)", + "hours (number)", + "minutes (number)", + "seconds (number)" + ) + +/obj/item/integrated_circuit/time/clock/work() + if(..()) + var/datum/integrated_io/time = outputs[1] + var/datum/integrated_io/hour = outputs[2] + var/datum/integrated_io/min = outputs[3] + var/datum/integrated_io/sec = outputs[4] + + time.data = time2text(station_time_in_ticks, "hh:mm:ss") + hour.data = text2num(time2text(station_time_in_ticks, "hh")) + min.data = text2num(time2text(station_time_in_ticks, "mm")) + sec.data = text2num(time2text(station_time_in_ticks, "ss")) + + for(var/datum/integrated_io/output/O in outputs) + O.push_data() \ No newline at end of file diff --git a/code/modules/integrated_electronics/tools.dm b/code/modules/integrated_electronics/tools.dm new file mode 100644 index 0000000000..75609ca59c --- /dev/null +++ b/code/modules/integrated_electronics/tools.dm @@ -0,0 +1,227 @@ +#define WIRE "wire" +#define WIRING "wiring" +#define UNWIRE "unwire" +#define UNWIRING "unwiring" + + +/obj/item/device/integrated_electronics/wirer + name = "circuit wirer" + desc = "It's a small wiring tool, with a wire roll, electric soldering iron, wire cutter, and more in one package. \ + The wires used are generally useful for small electronics, such as circuitboards and breadboards, as opposed to larger wires \ + used for power or data transmission." + icon = 'icons/obj/electronic_assemblies.dmi' + icon_state = "wirer-wire" + flags = CONDUCT + w_class = 2 + var/datum/integrated_io/selected_io = null + var/mode = WIRE + +/obj/item/device/integrated_electronics/wirer/New() + ..() + +/obj/item/device/integrated_electronics/wirer/update_icon() + icon_state = "wirer-[mode]" + +/obj/item/device/integrated_electronics/wirer/proc/wire(var/datum/integrated_io/io, mob/user) + if(mode == WIRE) + selected_io = io + user << "You attach a data wire to \the [selected_io.holder]'s [selected_io.name] data channel." + mode = WIRING + update_icon() + else if(mode == WIRING) + if(io == selected_io) + user << "Wiring \the [selected_io.holder]'s [selected_io.name] into itself is rather pointless." + return + if(io.io_type != selected_io.io_type) + user << "Those two types of channels are incompatable. The first is a [selected_io.io_type], \ + while the second is a [io.io_type]." + return + selected_io.linked |= io + io.linked |= selected_io + + user << "You connect \the [selected_io.holder]'s [selected_io.name] to \the [io.holder]'s [io.name]." + mode = WIRE + update_icon() + //io.updateDialog() + //selected_io.updateDialog() + selected_io.holder.interact(user) // This is to update the UI. + selected_io = null + + else if(mode == UNWIRE) + selected_io = io + if(!io.linked.len) + user << "There is nothing connected to \the [selected_io] data channel." + selected_io = null + return + user << "You prepare to detach a data wire from \the [selected_io.holder]'s [selected_io.name] data channel." + mode = UNWIRING + update_icon() + return + + else if(mode == UNWIRING) + if(io == selected_io) + user << "You can't wire a pin into each other, so unwiring \the [selected_io.holder] from \ + the same pin is rather moot." + return + if(selected_io in io.linked) + io.linked.Remove(selected_io) + selected_io.linked.Remove(io) + user << "You disconnect \the [selected_io.holder]'s [selected_io.name] from \ + \the [io.holder]'s [io.name]." + //io.updateDialog() + //selected_io.updateDialog() + selected_io.holder.interact(user) // This is to update the UI. + selected_io = null + mode = UNWIRE + update_icon() + else + user << "\The [selected_io.holder]'s [selected_io.name] and \the [io.holder]'s \ + [io.name] are not connected." + return + return + +/obj/item/device/integrated_electronics/wirer/attack_self(mob/user) + switch(mode) + if(WIRE) + mode = UNWIRE + if(WIRING) + if(selected_io) + user << "You decide not to wire the data channel." + selected_io = null + mode = UNWIRE + if(UNWIRE) + mode = WIRE + if(UNWIRING) + if(selected_io) + user << "You decide not to disconnect the data channel." + selected_io = null + mode = UNWIRE + update_icon() + user << "You set \the [src] to [mode]." + +#undef WIRE +#undef WIRING +#undef UNWIRE +#undef UNWIRING + +/obj/item/device/integrated_electronics/debugger + name = "circuit debugger" + desc = "This small tool allows one working with custom machinery to directly set data to a specific pin, useful for writing \ + settings to specific circuits, or for debugging purposes. It can also pulse activation pins." + icon = 'icons/obj/electronic_assemblies.dmi' + icon_state = "debugger" + flags = CONDUCT + w_class = 2 + var/data_to_write = null + var/accepting_refs = 0 + +/obj/item/device/integrated_electronics/debugger/attack_self(mob/user) + var/type_to_use = input("Please choose a type to use.","[src] type setting") as null|anything in list("string","number","ref", "null") + var/new_data = null + switch(type_to_use) + if("string") + accepting_refs = 0 + new_data = input("Now type in a string.","[src] string writing") as null|text + if(istext(new_data)) + data_to_write = new_data + user << "You set \the [src]'s memory to \"[new_data]\"." + if("number") + accepting_refs = 0 + new_data = input("Now type in a number.","[src] number writing") as null|num + if(isnum(new_data)) + data_to_write = new_data + user << "You set \the [src]'s memory to [new_data]." + if("ref") + accepting_refs = 1 + user << "You turn \the [src]'s ref scanner on. Slide it across \ + an object for a ref of that object to save it in memory." + if("null") + data_to_write = null + user << "You set \the [src]'s memory to absolutely nothing." + +/obj/item/device/integrated_electronics/debugger/afterattack(atom/target, mob/living/user, proximity) + if(accepting_refs && proximity) + data_to_write = target + visible_message("[user] slides \a [src]'s over \the [target].") + user << "You set \the [src]'s memory to a reference to [target.name] \[Ref\]. The ref scanner is \ + now off." + accepting_refs = 0 + +/obj/item/device/integrated_electronics/debugger/proc/write_data(var/datum/integrated_io/io, mob/user) + if(io.io_type == DATA_CHANNEL) + io.write_data_to_pin(data_to_write) + user << "You write [data_to_write] to \the [io.holder]'s [io]." + else if(io.io_type == PULSE_CHANNEL) + io.holder.work() + user << "You pulse \the [io.holder]'s [io]." + + io.holder.interact(user) // This is to update the UI. + +/obj/item/weapon/storage/bag/circuits + name = "circuit kit" + desc = "This kit's essential for any circuitry projects." + icon = 'icons/obj/electronic_assemblies.dmi' + icon_state = "circuit_kit" + w_class = 3 + storage_slots = 200 + max_storage_space = 400 + max_w_class = 3 + display_contents_with_number = 1 + can_hold = list(/obj/item/integrated_circuit, /obj/item/device/integrated_electronics, /obj/item/device/electronic_assembly, + /obj/item/weapon/screwdriver, /obj/item/weapon/crowbar) + +/obj/item/weapon/storage/bag/circuits/basic/New() + ..() + var/list/types_to_spawn = typesof(/obj/item/integrated_circuit/arithmetic, + /obj/item/integrated_circuit/logic, + /obj/item/integrated_circuit/memory, + ) - list(/obj/item/integrated_circuit/arithmetic, + /obj/item/integrated_circuit/memory, + /obj/item/integrated_circuit/logic, + ) + + types_to_spawn.Add(/obj/item/integrated_circuit/input/numberpad, + /obj/item/integrated_circuit/input/textpad, + /obj/item/integrated_circuit/input/button, + /obj/item/integrated_circuit/input/signaler, + /obj/item/integrated_circuit/input/local_locator, + /obj/item/integrated_circuit/output/screen, + /obj/item/integrated_circuit/converter/num2text, + /obj/item/integrated_circuit/converter/text2num, + /obj/item/integrated_circuit/converter/uppercase, + /obj/item/integrated_circuit/converter/lowercase, + /obj/item/integrated_circuit/time/delay/five_sec, + /obj/item/integrated_circuit/time/delay/one_sec, + /obj/item/integrated_circuit/time/delay/half_sec, + /obj/item/integrated_circuit/time/delay/tenth_sec, + /obj/item/integrated_circuit/time/ticker/slow, + /obj/item/integrated_circuit/time/clock + ) + + for(var/thing in types_to_spawn) + var/i = 3 + while(i) + new thing(src) + i-- + + new /obj/item/device/electronic_assembly(src) + new /obj/item/device/integrated_electronics/wirer(src) + new /obj/item/device/integrated_electronics/debugger(src) + new /obj/item/weapon/crowbar(src) + new /obj/item/weapon/screwdriver(src) + +/obj/item/weapon/storage/bag/circuits/all/New() + ..() + var/list/types_to_spawn = typesof(/obj/item/integrated_circuit) + + for(var/thing in types_to_spawn) + var/i = 10 + while(i) + new thing(src) + i-- + + new /obj/item/device/electronic_assembly(src) + new /obj/item/device/integrated_electronics/wirer(src) + new /obj/item/device/integrated_electronics/debugger(src) + new /obj/item/weapon/crowbar(src) + new /obj/item/weapon/screwdriver(src) \ No newline at end of file diff --git a/code/modules/mob/holder.dm b/code/modules/mob/holder.dm index b56435a59e..ab88819b53 100644 --- a/code/modules/mob/holder.dm +++ b/code/modules/mob/holder.dm @@ -50,6 +50,11 @@ var/list/holder_mob_icon_cache = list() continue M.forceMove(get_turf(src)) +/obj/item/weapon/holder/onDropInto(var/atom/movable/AM) + if(ismob(loc)) // Bypass our holding mob and drop directly to its loc + return loc.loc + return ..() + /obj/item/weapon/holder/GetID() for(var/mob/M in contents) var/obj/item/I = M.GetIdCard() diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm index ad71cebe1f..1c6e2436d4 100644 --- a/code/modules/mob/inventory.dm +++ b/code/modules/mob/inventory.dm @@ -126,16 +126,12 @@ var/list/slot_equipment_priority = list( \ // Removes an item from inventory and places it in the target atom. // If canremove or other conditions need to be checked then use unEquip instead. -/mob/proc/drop_from_inventory(var/obj/item/W, var/atom/Target = null) +/mob/proc/drop_from_inventory(var/obj/item/W, var/atom/target = null) if(W) - if(!Target) - Target = loc - - remove_from_mob(W) - if(!(W && W.loc)) return 1 // self destroying objects (tk, grabs) - - W.forceMove(Target) + remove_from_mob(W, target) + if(!(W && W.loc)) + return 1 // self destroying objects (tk, grabs) update_icons() return 1 return 0 @@ -194,7 +190,9 @@ var/list/slot_equipment_priority = list( \ //Attemps to remove an object on a mob. -/mob/proc/remove_from_mob(var/obj/O) +/mob/proc/remove_from_mob(var/obj/O, var/atom/target) + if(!O) // Nothing to remove, so we succeed. + return 1 src.u_equip(O) if (src.client) src.client.screen -= O @@ -202,7 +200,10 @@ var/list/slot_equipment_priority = list( \ O.screen_loc = null if(istype(O, /obj/item)) var/obj/item/I = O - I.forceMove(src.loc) + if(target) + I.forceMove(target) + else + I.dropInto(loc) I.dropped(src) return 1 diff --git a/code/modules/mob/living/bot/cleanbot.dm b/code/modules/mob/living/bot/cleanbot.dm index 6cb5908f6f..a6fc34f738 100644 --- a/code/modules/mob/living/bot/cleanbot.dm +++ b/code/modules/mob/living/bot/cleanbot.dm @@ -180,11 +180,11 @@ w_class = 3.0 var/created_name = "Cleanbot" -/obj/item/weapon/bucket_sensor/attackby(var/obj/item/O, var/mob/user) +/obj/item/weapon/bucket_sensor/attackby(var/obj/item/W, var/mob/user) ..() - if(istype(O, /obj/item/robot_parts/l_arm) || istype(O, /obj/item/robot_parts/r_arm)) + if(istype(W, /obj/item/robot_parts/l_arm) || istype(W, /obj/item/robot_parts/r_arm) || (istype(W, /obj/item/organ/external/arm) && ((W.name == "robotic left arm") || (W.name == "robotic right arm")))) user.drop_item() - qdel(O) + qdel(W) var/turf/T = get_turf(loc) var/mob/living/bot/cleanbot/A = new /mob/living/bot/cleanbot(T) A.name = created_name @@ -192,10 +192,10 @@ user.drop_from_inventory(src) qdel(src) - else if(istype(O, /obj/item/weapon/pen)) + else if(istype(W, /obj/item/weapon/pen)) var/t = sanitizeSafe(input(user, "Enter new robot name", name, created_name), MAX_NAME_LEN) if(!t) return if(!in_range(src, usr) && src.loc != usr) return - created_name = t + created_name = t \ No newline at end of file diff --git a/code/modules/mob/living/bot/ed209bot.dm b/code/modules/mob/living/bot/ed209bot.dm index ec4278c967..80279a4538 100644 --- a/code/modules/mob/living/bot/ed209bot.dm +++ b/code/modules/mob/living/bot/ed209bot.dm @@ -94,7 +94,7 @@ switch(build_step) if(0, 1) - if(istype(W, /obj/item/robot_parts/l_leg) || istype(W, /obj/item/robot_parts/r_leg)) + if(istype(W, /obj/item/robot_parts/l_leg) || istype(W, /obj/item/robot_parts/r_leg) || (istype(W, /obj/item/organ/external/leg) && ((W.name == "robotic right leg") || (W.name == "robotic left leg")))) user.drop_item() qdel(W) build_step++ diff --git a/code/modules/mob/living/bot/farmbot.dm b/code/modules/mob/living/bot/farmbot.dm index 42452c49fa..905c53a20a 100644 --- a/code/modules/mob/living/bot/farmbot.dm +++ b/code/modules/mob/living/bot/farmbot.dm @@ -337,6 +337,18 @@ new /obj/item/weapon/farmbot_arm_assembly(loc, src) +/obj/structure/reagent_dispensers/watertank/attackby(var/obj/item/organ/external/S, mob/user as mob) + if ((!istype(S, /obj/item/organ/external/arm)) && (!S.robotic == ORGAN_ROBOT)) + ..() + return + + user << "You add the robot arm to [src]." + + user.drop_from_inventory(S) + qdel(S) + + new /obj/item/weapon/farmbot_arm_assembly(loc, src) + /obj/item/weapon/farmbot_arm_assembly/attackby(obj/item/weapon/W as obj, mob/user as mob) ..() if((istype(W, /obj/item/device/analyzer/plant_analyzer)) && (build_step == 0)) diff --git a/code/modules/mob/living/bot/floorbot.dm b/code/modules/mob/living/bot/floorbot.dm index 0072d9a444..ca4f572775 100644 --- a/code/modules/mob/living/bot/floorbot.dm +++ b/code/modules/mob/living/bot/floorbot.dm @@ -339,7 +339,7 @@ /obj/item/weapon/toolbox_tiles_sensor/attackby(var/obj/item/W, mob/user as mob) ..() - if(istype(W, /obj/item/robot_parts/l_arm) || istype(W, /obj/item/robot_parts/r_arm)) + if(istype(W, /obj/item/robot_parts/l_arm) || istype(W, /obj/item/robot_parts/r_arm) || (istype(W, /obj/item/organ/external/arm) && ((W.name == "robotic right arm") || (W.name == "robotic left arm")))) qdel(W) var/turf/T = get_turf(user.loc) var/mob/living/bot/floorbot/A = new /mob/living/bot/floorbot(T) diff --git a/code/modules/mob/living/bot/medbot.dm b/code/modules/mob/living/bot/medbot.dm index 8a0c7564d1..fffe5879fa 100644 --- a/code/modules/mob/living/bot/medbot.dm +++ b/code/modules/mob/living/bot/medbot.dm @@ -286,6 +286,29 @@ user.drop_from_inventory(src) qdel(src) +/obj/item/weapon/storage/firstaid/attackby(var/obj/item/organ/external/S, mob/user as mob) + if (!istype(S, /obj/item/organ/external/arm) || !(S.robotic == ORGAN_ROBOT)) + ..() + return + + if(contents.len >= 1) + user << "You need to empty [src] out first." + return + + var/obj/item/weapon/firstaid_arm_assembly/A = new /obj/item/weapon/firstaid_arm_assembly + if(istype(src, /obj/item/weapon/storage/firstaid/fire)) + A.skin = "ointment" + else if(istype(src, /obj/item/weapon/storage/firstaid/toxin)) + A.skin = "tox" + else if(istype(src, /obj/item/weapon/storage/firstaid/o2)) + A.skin = "o2" + + qdel(S) + user.put_in_hands(A) + user << "You add the robot arm to the first aid kit." + user.drop_from_inventory(src) + qdel(src) + /obj/item/weapon/firstaid_arm_assembly name = "first aid/robot arm assembly" desc = "A first aid kit with a robot arm permanently grafted to it." diff --git a/code/modules/mob/living/bot/secbot.dm b/code/modules/mob/living/bot/secbot.dm index b07202572e..f7556e0ece 100644 --- a/code/modules/mob/living/bot/secbot.dm +++ b/code/modules/mob/living/bot/secbot.dm @@ -258,40 +258,40 @@ var/build_step = 0 var/created_name = "Securitron" -/obj/item/weapon/secbot_assembly/attackby(var/obj/item/O, var/mob/user) +/obj/item/weapon/secbot_assembly/attackby(var/obj/item/W, var/mob/user) ..() - if(istype(O, /obj/item/weapon/weldingtool) && !build_step) - var/obj/item/weapon/weldingtool/WT = O + if(istype(W, /obj/item/weapon/weldingtool) && !build_step) + var/obj/item/weapon/weldingtool/WT = W if(WT.remove_fuel(0, user)) build_step = 1 overlays += image('icons/obj/aibots.dmi', "hs_hole") user << "You weld a hole in \the [src]." - else if(isprox(O) && (build_step == 1)) + else if(isprox(W) && (build_step == 1)) user.drop_item() build_step = 2 - user << "You add \the [O] to [src]." + user << "You add \the [W] to [src]." overlays += image('icons/obj/aibots.dmi', "hs_eye") name = "helmet/signaler/prox sensor assembly" - qdel(O) + qdel(W) - else if((istype(O, /obj/item/robot_parts/l_arm) || istype(O, /obj/item/robot_parts/r_arm)) && build_step == 2) + else if((istype(W, /obj/item/robot_parts/l_arm) || istype(W, /obj/item/robot_parts/r_arm) || (istype(W, /obj/item/organ/external/arm) && ((W.name == "robotic right arm") || (W.name == "robotic left arm")))) && build_step == 2) user.drop_item() build_step = 3 - user << "You add \the [O] to [src]." + user << "You add \the [W] to [src]." name = "helmet/signaler/prox sensor/robot arm assembly" overlays += image('icons/obj/aibots.dmi', "hs_arm") - qdel(O) + qdel(W) - else if(istype(O, /obj/item/weapon/melee/baton) && build_step == 3) + else if(istype(W, /obj/item/weapon/melee/baton) && build_step == 3) user.drop_item() user << "You complete the Securitron! Beep boop." var/mob/living/bot/secbot/S = new /mob/living/bot/secbot(get_turf(src)) S.name = created_name - qdel(O) + qdel(W) qdel(src) - else if(istype(O, /obj/item/weapon/pen)) + else if(istype(W, /obj/item/weapon/pen)) var/t = sanitizeSafe(input(user, "Enter new robot name", name, created_name), MAX_NAME_LEN) if(!t) return diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm index dd9e4f28b9..aa4e6ced11 100644 --- a/code/modules/mob/living/carbon/carbon_defense.dm +++ b/code/modules/mob/living/carbon/carbon_defense.dm @@ -1,12 +1,11 @@ - //Called when the mob is hit with an item in combat. /mob/living/carbon/resolve_item_attack(obj/item/I, mob/living/user, var/effective_force, var/hit_zone) - if(check_attack_throat(I, user)) + if(check_neckgrab_attack(I, user, hit_zone)) return null ..() /mob/living/carbon/standard_weapon_hit_effects(obj/item/I, mob/living/user, var/effective_force, var/blocked, var/hit_zone) - if(!effective_force || blocked >= 100) + if(!effective_force || blocked >= 100) return 0 //Hulk modifier @@ -39,18 +38,23 @@ return 1 // Attacking someone with a weapon while they are neck-grabbed -/mob/living/carbon/proc/check_attack_throat(obj/item/W, mob/user) +/mob/living/carbon/proc/check_neckgrab_attack(obj/item/W, mob/user, var/hit_zone) if(user.a_intent == I_HURT) for(var/obj/item/weapon/grab/G in src.grabbed_by) - if(G.assailant == user && G.state >= GRAB_NECK) - if(attack_throat(W, G, user)) - return 1 + if(G.assailant == user) + if(G.state >= GRAB_AGGRESSIVE) + if(hit_zone == BP_TORSO && shank_attack(W, G, user)) + return 1 + if(G.state >= GRAB_NECK) + if(hit_zone == BP_HEAD && attack_throat(W, G, user, hit_zone)) + return 1 return 0 + // Knifing /mob/living/carbon/proc/attack_throat(obj/item/W, obj/item/weapon/grab/G, mob/user) - if(!W.edge || !W.force || W.damtype != BRUTE) + if(!W.edge || !W.force || W.damtype != BRUTE) return 0 //unsuitable weapon user.visible_message("\The [user] begins to slit [src]'s throat with \the [W]!") @@ -95,4 +99,59 @@ user.attack_log += "\[[time_stamp()]\] Knifed [name] ([ckey]) with [W.name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(W.damtype)])" src.attack_log += "\[[time_stamp()]\] Got knifed by [user.name] ([user.ckey]) with [W.name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(W.damtype)])" msg_admin_attack("[key_name(user)] knifed [key_name(src)] with [W.name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(W.damtype)])" ) - return 1 \ No newline at end of file + return 1 + +/mob/living/carbon/proc/shank_attack(obj/item/W, obj/item/weapon/grab/G, mob/user, hit_zone) + + if(!W.sharp || !W.force || W.damtype != BRUTE) + return 0 //unsuitable weapon + + user.visible_message("\The [user] plunges \the [W] into \the [src]!") + + var/damage = shank_armor_helper(W, G, user) + apply_damage(damage, W.damtype, "torso", 0, sharp=W.sharp, edge=W.edge) + + if(W.hitsound) + playsound(loc, W.hitsound, 50, 1, -1) + + user.attack_log += "\[[time_stamp()]\] Shanked [name] ([ckey]) with [W.name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(W.damtype)])" + src.attack_log += "\[[time_stamp()]\] Got shanked by [user.name] ([user.ckey]) with [W.name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(W.damtype)])" + msg_admin_attack("[key_name(user)] shanked [key_name(src)] with [W.name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(W.damtype)])" ) + + return 1 + +/mob/living/carbon/proc/shank_armor_helper(obj/item/W, obj/item/weapon/grab/G, mob/user) + var/damage = W.force + var/damage_mod = 1 + if(W.edge) + damage = damage * 1.25 //small damage bonus for having sharp and edge + + var/obj/item/clothing/suit/worn_suit + var/obj/item/clothing/under/worn_under + var/worn_suit_armor + var/worn_under_armor + + //if(slot_wear_suit) + if(get_equipped_item(slot_wear_suit)) + worn_suit = get_equipped_item(slot_wear_suit) + //worn_suit = get_equipped_item(slot_wear_suit) + worn_suit_armor = worn_suit.armor["melee"] + else + worn_suit_armor = 0 + + //if(slot_w_uniform) + if(get_equipped_item(slot_w_uniform)) + worn_under = get_equipped_item(slot_w_uniform) + //worn_under_armor = slot_w_uniform.armor["melee"] + worn_under_armor = worn_under.armor["melee"] + else + worn_under_armor = 0 + + if(worn_under_armor > worn_suit_armor) + damage_mod = 1 - (worn_under_armor/100) + else + damage_mod = 1 - (worn_suit_armor/100) + + damage = damage * damage_mod + + return damage \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index 7ac543f1f2..195816f255 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -67,7 +67,7 @@ BP_L_LEG = skiplegs, BP_R_LEG = skiplegs) - var/msg = "*---------*\nThis is " + var/list/msg = list("*---------*\nThis is ") var/datum/gender/T = gender_datums[get_gender()] if(skipjumpsuit && skipface) //big suits/masks/helmets make it hard to tell their gender @@ -253,8 +253,8 @@ //splints for(var/organ in list(BP_L_LEG, BP_R_LEG, BP_L_ARM, BP_R_ARM)) var/obj/item/organ/external/o = get_organ(organ) - if(o && o.status & ORGAN_SPLINTED) - msg += "[T.He] [T.has] a splint on [T.his] [o.name]!\n" + if(o && o.splinted && o.splinted.loc == o) + msg += "[T.He] [T.has] \a [o.splinted] on [T.his] [o.name]!\n" if(suiciding) msg += "[T.He] appears to have commited suicide... there is no hope of recovery.\n" @@ -316,6 +316,7 @@ var/list/wound_flavor_text = list() var/list/is_bleeding = list() + var/applying_pressure = "" for(var/organ_tag in species.has_limbs) @@ -349,8 +350,6 @@ wound_flavor_text["[temp.name]"] = "[T.He] has [temp.get_wounds_desc()] on [T.his] [parent.name].
" else wound_flavor_text["[temp.name]"] = "[T.He] has [temp.get_wounds_desc()] on [T.his] [temp.name].
" - if(temp.status & ORGAN_BLEEDING) - is_bleeding["[temp.name]"] = "[T.His] [temp.name] is bleeding!
" else wound_flavor_text["[temp.name]"] = "" if(temp.dislocated == 2) @@ -358,9 +357,14 @@ if(((temp.status & ORGAN_BROKEN) && temp.brute_dam > temp.min_broken_damage) || (temp.status & ORGAN_MUTATED)) wound_flavor_text["[temp.name]"] += "[T.His] [temp.name] is dented and swollen!
" + if(!wound_flavor_text["[temp.name]"] && (temp.status & ORGAN_BLEEDING)) + is_bleeding["[temp.name]"] = "[T.His] [temp.name] is bleeding!
" + + if(temp.applied_pressure == src) + applying_pressure = "[T.He] is applying pressure to [T.his] [temp.name].
" + for(var/limb in wound_flavor_text) msg += wound_flavor_text[limb] - is_bleeding[limb] = null for(var/limb in is_bleeding) msg += is_bleeding[limb] for(var/implant in get_visible_implants(0)) @@ -421,13 +425,14 @@ msg += "OOC Notes: \[View\]\n" // VOREStation End - msg += "*---------*
" + msg += "*---------*

" + msg += applying_pressure if (pose) if( findtext(pose,".",lentext(pose)) == 0 && findtext(pose,"!",lentext(pose)) == 0 && findtext(pose,"?",lentext(pose)) == 0 ) pose = addtext(pose,".") //Makes sure all emotes end with a period. - msg += "\n[T.He] [pose]" + msg += "[T.He] [pose]" - user << msg + user << jointext(msg, null) //Helper procedure. Called by /mob/living/carbon/human/examine() and /mob/living/carbon/human/Topic() to determine HUD access to security and medical records. /proc/hasHUD(mob/M as mob, hudtype) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index a53363e586..03a7b0db45 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -1018,7 +1018,7 @@ /mob/living/carbon/human/proc/handle_embedded_objects() for(var/obj/item/organ/external/organ in src.organs) - if(organ.status & ORGAN_SPLINTED) //Splints prevent movement. + if(organ.splinted) //Splints prevent movement. continue for(var/obj/item/O in organ.implants) if(!istype(O,/obj/item/weapon/implant) && prob(5)) //Moving with things stuck in you could be bad. diff --git a/code/modules/mob/living/carbon/human/human_attackhand.dm b/code/modules/mob/living/carbon/human/human_attackhand.dm index d638d779d1..e790d1b5fd 100644 --- a/code/modules/mob/living/carbon/human/human_attackhand.dm +++ b/code/modules/mob/living/carbon/human/human_attackhand.dm @@ -92,7 +92,7 @@ src << "You feel a breath of fresh air enter your lungs. It feels good." H << "Repeat at least every 7 seconds." - else + else if(!(M == src && apply_pressure(M, M.zone_sel.selecting))) help_shake_act(M) return 1 @@ -363,3 +363,38 @@ spawn(1) qdel(rgrab) return success + +/* + We want to ensure that a mob may only apply pressure to one organ of one mob at any given time. Currently this is done mostly implicitly through + the behaviour of do_after() and the fact that applying pressure to someone else requires a grab: + If you are applying pressure to yourself and attempt to grab someone else, you'll change what you are holding in your active hand which will stop do_mob() + If you are applying pressure to another and attempt to apply pressure to yourself, you'll have to switch to an empty hand which will also stop do_mob() + Changing targeted zones should also stop do_mob(), preventing you from applying pressure to more than one body part at once. +*/ +/mob/living/carbon/human/proc/apply_pressure(mob/living/user, var/target_zone) + var/obj/item/organ/external/organ = get_organ(target_zone) + if(!organ || !(organ.status & ORGAN_BLEEDING) || (organ.robotic >= ORGAN_ROBOT)) + return 0 + + if(organ.applied_pressure) + user << "Someone is already applying pressure to [user == src? "your [organ.name]" : "[src]'s [organ.name]"]." + return 0 + + if(user == src) + user.visible_message("\The [user] starts applying pressure to \his [organ.name]!", "You start applying pressure to your [organ.name]!") + else + user.visible_message("\The [user] starts applying pressure to [src]'s [organ.name]!", "You start applying pressure to [src]'s [organ.name]!") + spawn(0) + organ.applied_pressure = user + + //apply pressure as long as they stay still and keep grabbing + do_mob(user, src, INFINITY, target_zone, progress = 0) + + organ.applied_pressure = null + + if(user == src) + user.visible_message("\The [user] stops applying pressure to \his [organ.name]!", "You stop applying pressure to your [organ]!") + else + user.visible_message("\The [user] stops applying pressure to [src]'s [organ.name]!", "You stop applying pressure to [src]'s [organ.name]!") + + return 1 \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 1d716b519d..2adb24665b 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -147,7 +147,7 @@ emp_act ..() /mob/living/carbon/human/resolve_item_attack(obj/item/I, mob/living/user, var/target_zone) - if(check_attack_throat(I, user)) + if(check_neckgrab_attack(I, user, target_zone)) return null if(user == src) // Attacking yourself can't miss @@ -464,3 +464,30 @@ emp_act return perm +/mob/living/carbon/human/shank_attack(obj/item/W, obj/item/weapon/grab/G, mob/user, hit_zone) + + if(!..()) + return 0 + + var/organ_chance = 50 + var/damage = shank_armor_helper(W, G, user) + var/obj/item/organ/external/chest = get_organ(hit_zone) + + if(W.edge) + organ_chance = 75 + user.next_move = world.time + 20 + user.visible_message("\The [user] begins to twist \the [W] around inside [src]'s [chest]!") + if(!do_after(user, 20)) + return 0 + if(!(G && G.assailant == user && G.affecting == src)) //check that we still have a grab + return 0 + + user.visible_message("\The [user] twists \the [W] around inside [src]'s [chest]!") + + if(prob(organ_chance)) + var/obj/item/organ/internal/selected_organ = pick(chest.internal_organs) + selected_organ.damage = max(selected_organ.damage, damage * 0.5) + G.last_action = world.time + flick(G.hud.icon_state, G.hud) + + return 1 \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index ad6d078869..c225e63838 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -87,7 +87,8 @@ var/list/flavor_texts = list() var/gunshot_residue var/pulling_punches // Are you trying not to hurt your opponent? - var/robolimb_count = 0 // Number of robot limbs. + var/robolimb_count = 0 // Total number of external robot parts. + var/robobody_count = 0 // Counts torso, groin, and head, if they're robotic mob_bump_flag = HUMAN mob_push_flags = ~HEAVY diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm index ae9dd9a506..de4b36dceb 100644 --- a/code/modules/mob/living/carbon/human/human_movement.dm +++ b/code/modules/mob/living/carbon/human/human_movement.dm @@ -45,7 +45,7 @@ var/obj/item/organ/external/E = get_organ(organ_name) if(!E || E.is_stump()) tally += 4 - if(E.status & ORGAN_SPLINTED) + if(E.splinted) tally += 0.5 else if(E.status & ORGAN_BROKEN) tally += 1.5 @@ -57,7 +57,7 @@ var/obj/item/organ/external/E = get_organ(organ_name) if(!E || E.is_stump()) tally += 4 - else if(E.status & ORGAN_SPLINTED) + else if(E.splinted) tally += 0.5 else if(E.status & ORGAN_BROKEN) tally += 1.5 diff --git a/code/modules/mob/living/carbon/human/human_organs.dm b/code/modules/mob/living/carbon/human/human_organs.dm index 494126e312..97153394db 100644 --- a/code/modules/mob/living/carbon/human/human_organs.dm +++ b/code/modules/mob/living/carbon/human/human_organs.dm @@ -142,10 +142,10 @@ return for (var/obj/item/organ/external/E in organs) - if(!E || !E.can_grasp || (E.status & ORGAN_SPLINTED)) + if(!E || !E.can_grasp) continue - if(E.is_broken() || E.is_dislocated()) + if((E.is_broken() || E.is_dislocated()) && !E.splinted) switch(E.body_part) if(HAND_LEFT, ARM_LEFT) if(!l_hand) diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 8fc44a0671..ceef119b33 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -693,9 +693,9 @@ if (species.body_temperature == null) return //this species doesn't have metabolic thermoregulation - // Robolimbs cause overheating too. - if(robolimb_count) - bodytemperature += round(robolimb_count/2) + // FBPs will overheat, prosthetic limbs are fine. + if(robobody_count) + bodytemperature += round(robobody_count*1.75) var/body_temperature_difference = species.body_temperature - bodytemperature diff --git a/code/modules/mob/living/carbon/human/stripping.dm b/code/modules/mob/living/carbon/human/stripping.dm index f1c92b6255..d67eaf76a9 100644 --- a/code/modules/mob/living/carbon/human/stripping.dm +++ b/code/modules/mob/living/carbon/human/stripping.dm @@ -125,11 +125,13 @@ if(can_reach_splints) var/removed_splint for(var/obj/item/organ/external/o in organs) - if (o && o.status & ORGAN_SPLINTED) - var/obj/item/W = new /obj/item/stack/medical/splint(get_turf(src), 1) - o.status &= ~ORGAN_SPLINTED - W.add_fingerprint(user) - removed_splint = 1 + if (o && o.splinted) + var/obj/item/S = o.splinted + if(istype(S) && S.loc == o) //can only remove splints that are actually worn on the organ (deals with hardsuit splints) + S.add_fingerprint(user) + if(o.remove_splint()) + user.put_in_active_hand(S) + removed_splint = 1 if(removed_splint) visible_message("\The [user] removes \the [src]'s splints!") else diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index 6bc000f0f1..5c6868edc0 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -226,6 +226,7 @@ var/global/list/damage_icon_parts = list() var/skeleton = (SKELETON in src.mutations) robolimb_count = 0 + robobody_count = 0 //CACHING: Generate an index key from visible bodyparts. //0 = destroyed, 1 = normal, 2 = robotic, 3 = necrotic. @@ -257,6 +258,8 @@ var/global/list/damage_icon_parts = list() else if(part.robotic >= ORGAN_ROBOT) icon_key += "2[part.model ? "-[part.model]": ""]" robolimb_count++ + if(part.organ_tag == BP_HEAD || part.organ_tag == BP_TORSO || part.organ_tag == BP_GROIN) + robobody_count ++ else if(part.status & ORGAN_DEAD) icon_key += "3" else diff --git a/code/modules/mob/living/carbon/metroid/metroid.dm b/code/modules/mob/living/carbon/metroid/metroid.dm index b7a66b6842..3c0bfbdbad 100644 --- a/code/modules/mob/living/carbon/metroid/metroid.dm +++ b/code/modules/mob/living/carbon/metroid/metroid.dm @@ -381,8 +381,3 @@ powerlevel = 10 adjustToxLoss(-10) nutrition = max(nutrition, get_max_nutrition()) - -/mob/living/carbon/slime/cannot_use_vents() - if(Victim) - return "You cannot ventcrawl while feeding." - ..() diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 8fc7ef0f8c..bbb9a1acc8 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -651,126 +651,10 @@ default behaviour is: resting = !resting src << "You are now [resting ? "resting" : "getting up"]" -/mob/living/proc/is_allowed_vent_crawl_item(var/obj/item/carried_item) - return (get_inventory_slot(carried_item) == 0) - -/mob/living/simple_animal/spiderbot/is_allowed_vent_crawl_item(var/obj/item/carried_item) - if(carried_item == held_item) - return 0 - return ..() - -//called when the mob receives a bright flash -/mob/living/flash_eyes(intensity = FLASH_PROTECTION_MODERATE, override_blindness_check = FALSE, affect_silicon = FALSE, visual = FALSE, type = /obj/screen/fullscreen/flash) - if(override_blindness_check || !(disabilities & BLIND)) - overlay_fullscreen("flash", type) - spawn(25) - if(src) - clear_fullscreen("flash", 25) - return 1 - -/mob/living/proc/handle_ventcrawl(var/obj/machinery/atmospherics/unary/vent_pump/vent_found = null, var/ignore_items = 0) // -- TLE -- Merged by Carn - if(stat) - src << "You must be conscious to do this!" - return - if(lying) - src << "You can't vent crawl while you're stunned!" - return - var/special_fail_msg = cannot_use_vents() - if(special_fail_msg) - src << "[special_fail_msg]" - return - - if(vent_found) // one was passed in, probably from vent/AltClick() - if(vent_found.welded) - src << "That vent is welded shut." - return - if(!vent_found.Adjacent(src)) - return // don't even acknowledge that - else - for(var/obj/machinery/atmospherics/unary/vent_pump/v in range(1,src)) - if(!v.welded) - if(v.Adjacent(src)) - vent_found = v - if(!vent_found) - src << "You'll need a non-welded vent to crawl into!" - return - - if(!vent_found.network || !vent_found.network.normal_members.len) - src << "This vent is not connected to anything." - return - - var/list/vents = list() - for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in vent_found.network.normal_members) - if(temp_vent.welded) - continue - if(temp_vent in loc) - continue - var/turf/T = get_turf(temp_vent) - - if(!T || T.z != loc.z) - continue - - var/i = 1 - var/index = "[T.loc.name]\[[i]\]" - while(index in vents) - i++ - index = "[T.loc.name]\[[i]\]" - vents[index] = temp_vent - if(!vents.len) - src << "\red There are no available vents to travel to, they could be welded." - return - - var/obj/selection = input("Select a destination.", "Duct System") as null|anything in sortAssoc(vents) - if(!selection) return - - if(!vent_found.Adjacent(src)) - src << "Never mind, you left." - return - - if(!ignore_items) - var/list/badItems = list() - for(var/obj/item/carried_item in contents)//If the monkey got on objects. - if(!is_allowed_vent_crawl_item(carried_item)) - badItems += carried_item.name - if(badItems.len) - src << "Your [english_list(badItems)] prevent[badItems.len == 1 ? "s" : ""] you from ventcrawling." - return - - if(isslime(src)) - var/mob/living/carbon/slime/S = src - if(S.Victim) - src << "\red You'll have to let [S.Victim] go or finish eating \him first." - return - - var/obj/machinery/atmospherics/unary/vent_pump/target_vent = vents[selection] - if(!target_vent) - return - - for(var/mob/O in viewers(src, null)) - O.show_message(text("[src] scrambles into the ventillation ducts!"), 1) - loc = target_vent - - var/travel_time = round(get_dist(loc, target_vent.loc) / 2) - - spawn(travel_time) - - if(!target_vent) return - for(var/mob/O in hearers(target_vent,null)) - O.show_message("You hear something squeezing through the ventilation ducts.",2) - - sleep(travel_time) - - if(!target_vent) return - if(target_vent.welded) //the vent can be welded while alien scrolled through the list or travelled. - target_vent = vent_found //travel back. No additional time required. - src << "\red The vent you were heading to appears to be welded." - loc = target_vent.loc - var/area/new_area = get_area(loc) - if(new_area) - new_area.Entered(src) - /mob/living/proc/cannot_use_vents() - return "You can't fit into that vent." + if(mob_size > MOB_SMALL) + return "You can't fit into that vent." + return null /mob/living/proc/has_brain() return 1 diff --git a/code/modules/mob/living/living_powers.dm b/code/modules/mob/living/living_powers.dm index b4310d77b5..4fb4c1bcbd 100644 --- a/code/modules/mob/living/living_powers.dm +++ b/code/modules/mob/living/living_powers.dm @@ -1,13 +1,3 @@ -/mob/living/proc/ventcrawl() - set name = "Crawl through Vent" - set desc = "Enter an air vent and crawl through the pipe system." - set category = "Abilities" - - if(stat == DEAD || paralysis || weakened || stunned || restrained()) - return - - handle_ventcrawl() - /mob/living/proc/hide() set name = "Hide" set desc = "Allows to hide beneath tables or certain items. Toggled on or off." diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index 3c6f8585f6..fd38776dd5 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -400,7 +400,7 @@ var/list/ai_verbs_hidden = list( // For why this exists, refer to https://xkcd.c var/input = sanitize(input(usr, "Please choose a message to transmit to [boss_short] via quantum entanglement. Please be aware that this process is very expensive, and abuse will lead to... termination. Transmission does not guarantee a response. There is a 30 second delay before you may send another message, be clear, full and concise.", "To abort, send an empty message.", "")) if(!input) return - Centcomm_announce(input, usr) + CentCom_announce(input, usr) usr << "Message transmitted." log_say("[key_name(usr)] has made an IA [boss_short] announcement: [input]") emergency_message_cooldown = 1 diff --git a/code/modules/mob/living/silicon/ai/icons.dm b/code/modules/mob/living/silicon/ai/icons.dm index 83689c9dd4..ebd47cc02d 100644 --- a/code/modules/mob/living/silicon/ai/icons.dm +++ b/code/modules/mob/living/silicon/ai/icons.dm @@ -112,7 +112,7 @@ var/list/datum/ai_icon/ai_icons alive_light = "#585858" /datum/ai_icon/nanotrasen - name = "Nanotrasen" + name = "NanoTrasen" alive_icon = "ai-nanotrasen" alive_light = "#000029" diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index f9c26528b6..f038324299 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -465,6 +465,7 @@ return var/obj/item/weapon/weldingtool/WT = W if (WT.remove_fuel(0)) + user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) adjustBruteLoss(-30) updatehealth() add_fingerprint(user) @@ -480,6 +481,7 @@ return var/obj/item/stack/cable_coil/coil = W if (coil.use(1)) + user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) adjustFireLoss(-30) updatehealth() for(var/mob/O in viewers(user, null)) diff --git a/code/modules/mob/living/simple_animal/friendly/penguin.dm b/code/modules/mob/living/simple_animal/friendly/penguin.dm new file mode 100644 index 0000000000..b843013c39 --- /dev/null +++ b/code/modules/mob/living/simple_animal/friendly/penguin.dm @@ -0,0 +1,19 @@ +/mob/living/simple_animal/penguin + name = "space penguin" + desc = "An ungainly, waddling, cute, and VERY well-dressed bird." + icon_state = "penguin" + icon_living = "penguin" + icon_dead = "penguin_dead" + icon_gib = "generic_gib" + speak_chance = 0 + turns_per_move = 5 + maxHealth = 20 + health = 20 + meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat + response_help = "pets" + response_disarm = "pushes aside" + response_harm = "hits" + harm_intent_damage = 5 + melee_damage_upper = 15 + melee_damage_lower = 10 + attacktext = "pecked" \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/hostile/goose.dm b/code/modules/mob/living/simple_animal/hostile/goose.dm new file mode 100644 index 0000000000..0f2c4af611 --- /dev/null +++ b/code/modules/mob/living/simple_animal/hostile/goose.dm @@ -0,0 +1,34 @@ + + +/mob/living/simple_animal/hostile/goose + name = "space goose" + desc = "That's no duck. That's a space goose. You have a bad feeling about this." + icon_state = "goose" + icon_living = "goose" + icon_dead = "goose_dead" + icon_gib = "generic_gib" + speak_chance = 0 + turns_per_move = 5 + meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat + response_help = "pets the" + response_disarm = "gently pushes aside the" + response_harm = "hits the" + speed = 4 + maxHealth = 15 //nothing an unarmed crewmember shouldn't be able to stomp into the dirt, if they're alone. + health = 15 + + harm_intent_damage = 5 + melee_damage_lower = 5 //they're meant to be annoying, not threatening. + melee_damage_upper = 5 //unless there's like a dozen of them, then you're screwed. + attacktext = "pecked" + attack_sound = 'sound/weapons/bite.ogg' + + break_stuff_probability = 5 + + faction = "geese" + + +/mob/living/simple_animal/hostile/goose/FindTarget() + . = ..() + if(.) + custom_emote(1,"flaps and honks at [.]!") \ No newline at end of file diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 75f061e2e1..41cbbbc5e9 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -520,7 +520,7 @@ for(var/name in H.organs_by_name) var/obj/item/organ/external/e = H.organs_by_name[name] if(e && H.lying) - if(((e.status & ORGAN_BROKEN && !(e.status & ORGAN_SPLINTED)) || e.status & ORGAN_BLEEDING) && (H.getBruteLoss() + H.getFireLoss() >= 100)) + if(((e.status & ORGAN_BROKEN && !(e.splinted)) || e.status & ORGAN_BLEEDING) && (H.getBruteLoss() + H.getFireLoss() >= 100)) return 1 break return 0 diff --git a/code/modules/mob/mob_grab.dm b/code/modules/mob/mob_grab.dm index e40b14dffd..a7b982b1b7 100644 --- a/code/modules/mob/mob_grab.dm +++ b/code/modules/mob/mob_grab.dm @@ -301,6 +301,7 @@ //clicking on the victim while grabbing them if(M == affecting) if(ishuman(affecting)) + var/mob/living/carbon/human/H = affecting var/hit_zone = assailant.zone_sel.selecting flick(hud.icon_state, hud) switch(assailant.a_intent) @@ -309,7 +310,10 @@ assailant << "You are no longer pinning [affecting] to the ground." force_down = 0 return - inspect_organ(affecting, assailant, hit_zone) + if(state >= GRAB_AGGRESSIVE) + H.apply_pressure(assailant, hit_zone) + else + inspect_organ(affecting, assailant, hit_zone) if(I_GRAB) jointlock(affecting, assailant, hit_zone) diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm index c2b83551ec..f50b91f291 100644 --- a/code/modules/mob/new_player/new_player.dm +++ b/code/modules/mob/new_player/new_player.dm @@ -371,7 +371,7 @@ dat += "Welcome, [name].
" dat += "Round Duration: [roundduration2text()]
" - if(emergency_shuttle) //In case Nanotrasen decides reposess CentComm's shuttles. + if(emergency_shuttle) //In case NanoTrasen decides reposess CentCom's shuttles. if(emergency_shuttle.going_to_centcom()) //Shuttle is going to centcomm, not recalled dat += "The station has been evacuated.
" if(emergency_shuttle.online()) diff --git a/code/modules/mob/new_player/preferences_setup.dm b/code/modules/mob/new_player/preferences_setup.dm index a10049a644..92f0f512bd 100644 --- a/code/modules/mob/new_player/preferences_setup.dm +++ b/code/modules/mob/new_player/preferences_setup.dm @@ -29,7 +29,7 @@ all_underwear[WRC.name] = WRI.name - backbag = rand(1,4) + backbag = rand(1,5) pdachoice = rand(1,3) age = rand(current_species.min_age, current_species.max_age) b_type = RANDOM_BLOOD_TYPE diff --git a/code/modules/multiz/pipes.dm b/code/modules/multiz/pipes.dm index 85e23b6797..1cb5b9b4da 100644 --- a/code/modules/multiz/pipes.dm +++ b/code/modules/multiz/pipes.dm @@ -13,9 +13,6 @@ obj/machinery/atmospherics/pipe/zpipe dir = SOUTH initialize_directions = SOUTH - var/obj/machinery/atmospherics/node1 //connection on the same Z - var/obj/machinery/atmospherics/node2 //connection on the other Z - var/minimum_temperature_difference = 300 var/thermal_conductivity = 0 //WALL_HEAT_TRANSFER_COEFFICIENT No diff --git a/code/modules/organs/blood.dm b/code/modules/organs/blood.dm index c167f949fa..7637264bac 100644 --- a/code/modules/organs/blood.dm +++ b/code/modules/organs/blood.dm @@ -128,8 +128,18 @@ var/const/BLOOD_VOLUME_SURVIVE = 40 for(var/obj/item/organ/external/temp in organs) if(!(temp.status & ORGAN_BLEEDING) || (temp.robotic >= ORGAN_ROBOT)) continue - for(var/datum/wound/W in temp.wounds) if(W.bleeding()) - blood_max += W.damage / 30 + for(var/datum/wound/W in temp.wounds) + if(W.bleeding()) + if(temp.applied_pressure) + if(ishuman(temp.applied_pressure)) + var/mob/living/carbon/human/H = temp.applied_pressure + H.bloody_hands(src, 0) + //somehow you can apply pressure to every wound on the organ at the same time + //you're basically forced to do nothing at all, so let's make it pretty effective + var/min_eff_damage = max(0, W.damage - 10) / 6 //still want a little bit to drip out, for effect + blood_max += max(min_eff_damage, W.damage - 30) / 30 + else + blood_max += W.damage / 30 if (temp.open) blood_max += 2 //Yer stomach is cut open drip(blood_max) diff --git a/code/modules/organs/internal/appendix.dm b/code/modules/organs/internal/appendix.dm index b3fdc28bc2..f756b71efa 100644 --- a/code/modules/organs/internal/appendix.dm +++ b/code/modules/organs/internal/appendix.dm @@ -46,7 +46,7 @@ var/datum/wound/W = new /datum/wound/internal_bleeding(20) owner.adjustToxLoss(25) groin.wounds += W - inflamed = 0 + inflamed = 1 /obj/item/organ/internal/appendix/removed() if(inflamed) diff --git a/code/modules/organs/organ.dm b/code/modules/organs/organ.dm index fad60cc0d7..c3a349df17 100644 --- a/code/modules/organs/organ.dm +++ b/code/modules/organs/organ.dm @@ -254,7 +254,6 @@ var/list/organ_cache = list() robotic = ORGAN_ROBOT src.status &= ~ORGAN_BROKEN src.status &= ~ORGAN_BLEEDING - src.status &= ~ORGAN_SPLINTED src.status &= ~ORGAN_CUT_AWAY /obj/item/organ/proc/mechassist() //Used to add things like pacemakers, etc diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm index 612cda4a98..49917d8a23 100644 --- a/code/modules/organs/organ_external.dm +++ b/code/modules/organs/organ_external.dm @@ -38,6 +38,7 @@ var/list/s_col // skin colour var/list/h_col // hair colour var/body_hair // Icon blend for body hair if any. + var/mob/living/applied_pressure // Wound and structural data. var/wound_update_accuracy = 1 // how often wounds should be updated, a higher number means less often @@ -50,6 +51,7 @@ var/list/implants = list() // Currently implanted objects. var/organ_rel_size = 25 // Relative size of the organ. var/base_miss_chance = 20 // Chance of missing. + var/atom/movable/splinted // Joint/state stuff. var/can_grasp // It would be more appropriate if these two were named "affects_grasp" and "affects_stand" at this point @@ -84,6 +86,10 @@ for(var/obj/item/organ/O in internal_organs) qdel(O) + if(splinted && splinted.loc == src) + qdel(splinted) + splinted = null + if(owner) owner.organs -= src owner.organs_by_name[organ_tag] = null @@ -524,11 +530,11 @@ This function completely restores a damaged organ to perfect condition. //external organs handle brokenness a bit differently when it comes to damage. Instead brute_dam is checked inside process() //this also ensures that an external organ cannot be "broken" without broken_description being set. /obj/item/organ/external/is_broken() - return ((status & ORGAN_CUT_AWAY) || ((status & ORGAN_BROKEN) && !(status & ORGAN_SPLINTED))) + return ((status & ORGAN_CUT_AWAY) || ((status & ORGAN_BROKEN) && !(splinted))) //Determines if we even need to process this organ. /obj/item/organ/external/proc/need_process() - if(status & (ORGAN_CUT_AWAY|ORGAN_BLEEDING|ORGAN_BROKEN|ORGAN_DESTROYED|ORGAN_SPLINTED|ORGAN_DEAD|ORGAN_MUTATED)) + if(status & (ORGAN_CUT_AWAY|ORGAN_BLEEDING|ORGAN_BROKEN|ORGAN_DESTROYED|ORGAN_DEAD|ORGAN_MUTATED)) return 1 if((brute_dam || burn_dam) && (robotic < ORGAN_ROBOT)) //Robot limbs don't autoheal and thus don't need to process when damaged return 1 @@ -1006,21 +1012,10 @@ Note that amputating the affected organ does in fact remove the infection from t // This is mostly for the ninja suit to stop ninja being so crippled by breaks. // TODO: consider moving this to a suit proc or process() or something during // hardsuit rewrite. - if(owner && !(status & ORGAN_SPLINTED) && istype(owner,/mob/living/carbon/human)) - var/mob/living/carbon/human/H = owner - - if(H.wear_suit && istype(H.wear_suit,/obj/item/clothing/suit/space)) - - var/obj/item/clothing/suit/space/suit = H.wear_suit - - if(isnull(suit.supporting_limbs)) - return - - owner << "You feel \the [suit] constrict about your [name], supporting it." - status |= ORGAN_SPLINTED - suit.supporting_limbs |= src - return + if(!(splinted) && owner && istype(owner.wear_suit, /obj/item/clothing/suit/space)) + var/obj/item/clothing/suit/space/suit = owner.wear_suit + suit.handle_fracture(owner, src) /obj/item/organ/external/proc/mend_fracture() if(robotic >= ORGAN_ROBOT) @@ -1031,6 +1026,24 @@ Note that amputating the affected organ does in fact remove the infection from t status &= ~ORGAN_BROKEN return 1 +/obj/item/organ/external/proc/apply_splint(var/atom/movable/splint) + if(!splinted) + splinted = splint + if(!applied_pressure) + applied_pressure = splint + return 1 + return 0 + +/obj/item/organ/external/proc/remove_splint() + if(splinted) + if(splinted.loc == src) + splinted.dropInto(owner? owner.loc : src.loc) + if(applied_pressure == splinted) + applied_pressure = null + splinted = null + return 1 + return 0 + /obj/item/organ/external/robotize(var/company, var/skip_prosthetics = 0, var/keep_organs = 0) if(robotic >= ORGAN_ROBOT) @@ -1054,6 +1067,7 @@ Note that amputating the affected organ does in fact remove the infection from t dislocated = -1 cannot_break = 1 + remove_splint() get_icon() unmutate() @@ -1235,11 +1249,20 @@ Note that amputating the affected organ does in fact remove the infection from t for(var/datum/wound/W in wounds) if(W.internal && !open) continue // can't see internal wounds var/this_wound_desc = W.desc - if(W.damage_type == BURN && W.salved) this_wound_desc = "salved [this_wound_desc]" - if(W.bleeding()) this_wound_desc = "bleeding [this_wound_desc]" - else if(W.bandaged) this_wound_desc = "bandaged [this_wound_desc]" - if(W.germ_level > 600) this_wound_desc = "badly infected [this_wound_desc]" - else if(W.germ_level > 330) this_wound_desc = "lightly infected [this_wound_desc]" + + if(W.damage_type == BURN && W.salved) + this_wound_desc = "salved [this_wound_desc]" + + if(W.bleeding()) + this_wound_desc = "bleeding [this_wound_desc]" + else if(W.bandaged) + this_wound_desc = "bandaged [this_wound_desc]" + + if(W.germ_level > 600) + this_wound_desc = "badly infected [this_wound_desc]" + else if(W.germ_level > 330) + this_wound_desc = "lightly infected [this_wound_desc]" + if(wound_descriptors[this_wound_desc]) wound_descriptors[this_wound_desc] += W.amount else diff --git a/code/modules/paperwork/adminpaper.dm b/code/modules/paperwork/adminpaper.dm index 7843552f8c..230d8984e8 100644 --- a/code/modules/paperwork/adminpaper.dm +++ b/code/modules/paperwork/adminpaper.dm @@ -40,7 +40,7 @@ var/originhash = md5("[origin]") var/timehash = copytext(md5("[world.time]"),1,10) var/text = null - var/logo = alert(usr, "Do you want the header of your fax to have a Nanotrasen or SolGov logo?","Fax Logo","Nanotrasen","SolGov") + var/logo = alert(usr, "Do you want the header of your fax to have a NanoTrasen or SolGov logo?","Fax Logo","NanoTrasen","SolGov") if(logo == "SolGov") logo = "sglogo.png" else diff --git a/code/modules/paperwork/faxmachine.dm b/code/modules/paperwork/faxmachine.dm index cf1da677f0..f2c309ff03 100644 --- a/code/modules/paperwork/faxmachine.dm +++ b/code/modules/paperwork/faxmachine.dm @@ -181,11 +181,11 @@ var/list/adminfaxes = list() //cache for faxes that have been sent to admins //message badmins that a fax has arrived if (destination == boss_name) - message_admins(sender, "[uppertext(boss_short)] FAX", rcvdcopy, "CentcommFaxReply", "#006100") + message_admins(sender, "[uppertext(boss_short)] FAX", rcvdcopy, "CentComFaxReply", "#006100") else if ("Sif Governmental Authority") - message_admins(sender, "SIF GOVERNMENT FAX", rcvdcopy, "CentcommFaxReply", "#1F66A0") + message_admins(sender, "SIF GOVERNMENT FAX", rcvdcopy, "CentComFaxReply", "#1F66A0") else if ("Supply") - message_admins(sender, "[uppertext(boss_short)] SUPPLY FAX", rcvdcopy, "CentcommFaxReply", "#5F4519") + message_admins(sender, "[uppertext(boss_short)] SUPPLY FAX", rcvdcopy, "CentComFaxReply", "#5F4519") else message_admins(sender, "[uppertext(destination)] FAX", rcvdcopy, "UNKNOWN") diff --git a/code/modules/projectiles/effects.dm b/code/modules/projectiles/effects.dm index 2235f188e7..94e39f41cc 100644 --- a/code/modules/projectiles/effects.dm +++ b/code/modules/projectiles/effects.dm @@ -11,7 +11,8 @@ if(istype(M)) transform = M -/obj/effect/projectile/proc/activate(var/kill_delay = 3) +/obj/effect/projectile/proc/activate(var/kill_delay = 5) + update_light() spawn(kill_delay) qdel(src) //see effect_system.dm - sets loc to null and lets GC handle removing these effects @@ -22,117 +23,207 @@ //---------------------------- /obj/effect/projectile/laser/tracer icon_state = "beam" + light_range = 2 + light_power = 0.5 + light_color = "#FF0D00" /obj/effect/projectile/laser/muzzle icon_state = "muzzle_laser" + light_range = 2 + light_power = 0.5 + light_color = "#FF0D00" /obj/effect/projectile/laser/impact icon_state = "impact_laser" + light_range = 2 + light_power = 0.5 + light_color = "#FF0D00" //---------------------------- // Blue laser beam //---------------------------- /obj/effect/projectile/laser_blue/tracer icon_state = "beam_blue" + light_range = 2 + light_power = 0.5 + light_color = "#0066FF" /obj/effect/projectile/laser_blue/muzzle icon_state = "muzzle_blue" + light_range = 2 + light_power = 0.5 + light_color = "#0066FF" /obj/effect/projectile/laser_blue/impact icon_state = "impact_blue" + light_range = 2 + light_power = 0.5 + light_color = "#0066FF" //---------------------------- // Omni laser beam //---------------------------- /obj/effect/projectile/laser_omni/tracer icon_state = "beam_omni" + light_range = 2 + light_power = 0.5 + light_color = "#00C6FF" /obj/effect/projectile/laser_omni/muzzle icon_state = "muzzle_omni" + light_range = 2 + light_power = 0.5 + light_color = "#00C6FF" /obj/effect/projectile/laser_omni/impact icon_state = "impact_omni" + light_range = 2 + light_power = 0.5 + light_color = "#00C6FF" //---------------------------- // Xray laser beam //---------------------------- /obj/effect/projectile/xray/tracer icon_state = "xray" + light_range = 2 + light_power = 0.5 + light_color = "#00CC33" /obj/effect/projectile/xray/muzzle icon_state = "muzzle_xray" + light_range = 2 + light_power = 0.5 + light_color = "#00CC33" /obj/effect/projectile/xray/impact icon_state = "impact_xray" + light_range = 2 + light_power = 0.5 + light_color = "#00CC33" //---------------------------- // Heavy laser beam //---------------------------- /obj/effect/projectile/laser_heavy/tracer icon_state = "beam_heavy" + light_range = 3 + light_power = 1 + light_color = "#FF0D00" /obj/effect/projectile/laser_heavy/muzzle icon_state = "muzzle_beam_heavy" + light_range = 3 + light_power = 1 + light_color = "#FF0D00" /obj/effect/projectile/laser_heavy/impact icon_state = "impact_beam_heavy" + light_range = 3 + light_power = 1 + light_color = "#FF0D00" //---------------------------- // Pulse laser beam //---------------------------- /obj/effect/projectile/laser_pulse/tracer icon_state = "u_laser" + light_range = 2 + light_power = 0.5 + light_color = "#0066FF" /obj/effect/projectile/laser_pulse/muzzle icon_state = "muzzle_u_laser" + light_range = 2 + light_power = 0.5 + light_color = "#0066FF" /obj/effect/projectile/laser_pulse/impact icon_state = "impact_u_laser" + light_range = 2 + light_power = 0.5 + light_color = "#0066FF" //---------------------------- // Pulse muzzle effect only //---------------------------- /obj/effect/projectile/pulse/muzzle icon_state = "muzzle_pulse" + light_range = 2 + light_power = 0.5 + light_color = "#0066FF" //---------------------------- // Emitter beam //---------------------------- /obj/effect/projectile/emitter/tracer icon_state = "emitter" + icon_state = "impact_xray" + light_range = 2 + light_power = 0.5 + light_color = "#00CC33" /obj/effect/projectile/emitter/muzzle icon_state = "muzzle_emitter" + icon_state = "impact_xray" + light_range = 2 + light_power = 0.5 + light_color = "#00CC33" /obj/effect/projectile/emitter/impact icon_state = "impact_emitter" + icon_state = "impact_xray" + light_range = 2 + light_power = 0.5 + light_color = "#00CC33" //---------------------------- // Stun beam //---------------------------- /obj/effect/projectile/stun/tracer icon_state = "stun" + light_range = 2 + light_power = 0.5 + light_color = "#FFFFFF" /obj/effect/projectile/stun/muzzle icon_state = "muzzle_stun" + light_range = 2 + light_power = 0.5 + light_color = "#FFFFFF" /obj/effect/projectile/stun/impact icon_state = "impact_stun" + light_range = 2 + light_power = 0.5 + light_color = "#FFFFFF" //---------------------------- // Bullet //---------------------------- /obj/effect/projectile/bullet/muzzle icon_state = "muzzle_bullet" + light_range = 2 + light_power = 0.5 + light_color = "#FFFFFF" //---------------------------- // Lightning beam //---------------------------- /obj/effect/projectile/lightning/tracer icon_state = "lightning" + light_range = 2 + light_power = 0.5 + light_color = "#00C6FF" /obj/effect/projectile/lightning/muzzle icon_state = "muzzle_lightning" + light_range = 2 + light_power = 0.5 + light_color = "#00C6FF" /obj/effect/projectile/lightning/impact - icon_state = "impact_lightning" \ No newline at end of file + icon_state = "impact_lightning" + light_range = 2 + light_power = 0.5 + light_color = "#00C6FF" \ No newline at end of file diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index 9271e50503..01dfce8e8c 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -290,6 +290,76 @@ if(muzzle_flash) set_light(0) +// Similar to the above proc, but does not require a user, which is ideal for things like turrets. +/obj/item/weapon/gun/proc/Fire_userless(atom/target) + if(!target) + return + + if(world.time < next_fire_time) + return + + var/shoot_time = (burst - 1)* burst_delay + next_fire_time = world.time + shoot_time + + var/turf/targloc = get_turf(target) //cache this in case target gets deleted during shooting, e.g. if it was a securitron that got destroyed. + for(var/i in 1 to burst) + var/obj/projectile = consume_next_projectile() + if(!projectile) + handle_click_empty() + break + + if(istype(projectile, /obj/item/projectile)) + var/obj/item/projectile/P = projectile + + var/acc = burst_accuracy[min(i, burst_accuracy.len)] + var/disp = dispersion[min(i, dispersion.len)] + + P.accuracy = accuracy + acc + P.dispersion = disp + + P.shot_from = src.name + P.silenced = silenced + + P.launch(target) + + if(silenced) + playsound(src, fire_sound, 10, 1) + else + playsound(src, fire_sound, 50, 1) + + if(muzzle_flash) + set_light(muzzle_flash) + update_icon() + + //process_accuracy(projectile, user, target, acc, disp) + + // if(pointblank) + // process_point_blank(projectile, user, target) + + // if(process_projectile(projectile, null, target, user.zone_sel.selecting, clickparams)) + // handle_post_fire(null, target, pointblank, reflex) + + // update_icon() + + if(i < burst) + sleep(burst_delay) + + if(!(target && target.loc)) + target = targloc + //pointblank = 0 + + log_and_message_admins("Fired [src].") + + //admin_attack_log(usr, attacker_message="Fired [src]", admin_message="fired a gun ([src]) (MODE: [src.mode_name]) [reflex ? "by reflex" : "manually"].") + + //update timing + next_fire_time = world.time + fire_delay + + if(muzzle_flash) + set_light(0) + + + //obtains the next projectile to fire /obj/item/weapon/gun/proc/consume_next_projectile() return null diff --git a/code/modules/projectiles/guns/energy/laser.dm b/code/modules/projectiles/guns/energy/laser.dm index 5d2fe06fa4..cef84810bd 100644 --- a/code/modules/projectiles/guns/energy/laser.dm +++ b/code/modules/projectiles/guns/energy/laser.dm @@ -6,7 +6,7 @@ item_state = "laser" fire_sound = 'sound/weapons/Laser.ogg' slot_flags = SLOT_BELT|SLOT_BACK - w_class = 3 + w_class = 4 force = 10 origin_tech = list(TECH_COMBAT = 3, TECH_MAGNET = 2) matter = list(DEFAULT_WALL_MATERIAL = 2000) @@ -69,8 +69,9 @@ obj/item/weapon/gun/energy/retro origin_tech = list(TECH_COMBAT = 4, TECH_MATERIAL = 3, TECH_POWER = 3) slot_flags = SLOT_BELT|SLOT_BACK projectile_type = /obj/item/projectile/beam/heavylaser/cannon - max_shots = 1 - fire_delay = 30 + max_shots = 4 + fire_delay = 20 + w_class = 4 // requires_two_hands = 1 one_handed_penalty = 6 // The thing's heavy and huge. accuracy = 3 diff --git a/code/modules/projectiles/guns/energy/nuclear.dm b/code/modules/projectiles/guns/energy/nuclear.dm index 2352cdce28..6819c1cd81 100644 --- a/code/modules/projectiles/guns/energy/nuclear.dm +++ b/code/modules/projectiles/guns/energy/nuclear.dm @@ -24,11 +24,14 @@ /obj/item/weapon/gun/energy/gun/burst name = "burst laser" - desc = "The FM-2t is a versatile energy based small arm, capable of switching between stun or kill with a three round burst option for both settings." - icon_state = "fm-2tstun100" + desc = "The FM-2t is a versatile energy based weapon, capable of switching between stun or kill with a three round burst option for both settings." + icon_state = "fm-2tstun100" //May resprite this to be more rifley item_state = null //so the human update icon uses the icon_state instead. fire_sound = 'sound/weapons/Taser.ogg' - max_shots = 21 //7 trigger pulls + max_shots = 18 + force = 8 + w_class = 4 //Probably gonna make it a rifle sooner or later + fire_delay = 6 projectile_type = /obj/item/projectile/beam/stun/weak origin_tech = list(TECH_COMBAT = 4, TECH_MAGNET = 2, TECH_ILLEGAL = 3) @@ -39,9 +42,9 @@ firemodes = list( list(mode_name="stun", burst=1, projectile_type=/obj/item/projectile/beam/stun/weak, modifystate="fm-2tstun", fire_sound='sound/weapons/Taser.ogg'), - list(mode_name="stun burst", burst=3, fire_delay=null, move_delay=4, burst_accuracy=list(0,-1,-1), dispersion=list(0.0, 0.6, 1.0), projectile_type=/obj/item/projectile/beam/stun/weak, modifystate="fm-2tstun", fire_sound='sound/weapons/Taser.ogg'), - list(mode_name="lethal", burst=1, projectile_type=/obj/item/projectile/beam/weaklaser, modifystate="fm-2tkill", fire_sound='sound/weapons/Laser.ogg'), - list(mode_name="lethal burst", burst=3, fire_delay=null, move_delay=4, burst_accuracy=list(0,-1,-1), dispersion=list(0.0, 0.6, 1.0), projectile_type=/obj/item/projectile/beam/weaklaser, modifystate="fm-2tkill", fire_sound='sound/weapons/Laser.ogg'), + list(mode_name="stun burst", burst=3, fire_delay=null, move_delay=4, burst_accuracy=list(0,0,0), dispersion=list(0.0, 0.2, 0.5), projectile_type=/obj/item/projectile/beam/stun/weak, modifystate="fm-2tstun", fire_sound='sound/weapons/Taser.ogg'), + list(mode_name="lethal", burst=1, projectile_type=/obj/item/projectile/beam/burstlaser, modifystate="fm-2tkill", fire_sound='sound/weapons/Laser.ogg'), + list(mode_name="lethal burst", burst=3, fire_delay=null, move_delay=4, burst_accuracy=list(0,0,0), dispersion=list(0.0, 0.2, 0.5), projectile_type=/obj/item/projectile/beam/burstlaser, modifystate="fm-2tkill", fire_sound='sound/weapons/Laser.ogg'), ) /obj/item/weapon/gun/energy/gun/nuclear @@ -51,6 +54,8 @@ origin_tech = list(TECH_COMBAT = 3, TECH_MATERIAL = 5, TECH_POWER = 3) slot_flags = SLOT_BELT force = 8 //looks heavier than a pistol + w_class = 4 //Looks bigger than a pistol, too. + fire_delay = 6 //This one's not a handgun, it should have the same fire delay as everything else self_recharge = 1 modifystate = null diff --git a/code/modules/projectiles/guns/projectile.dm b/code/modules/projectiles/guns/projectile.dm index d1fc9ee4a8..93904387cd 100644 --- a/code/modules/projectiles/guns/projectile.dm +++ b/code/modules/projectiles/guns/projectile.dm @@ -141,6 +141,24 @@ user.visible_message("[user] inserts \a [C] into [src].", "You insert \a [C] into [src].") playsound(src.loc, 'sound/weapons/empty.ogg', 50, 1) + else if(istype(A, /obj/item/weapon/storage)) + var/obj/item/weapon/storage/storage = A + if(!(load_method & SINGLE_CASING)) + return //incompatible + + user << "You start loading \the [src]." + sleep(1 SECOND) + for(var/obj/item/ammo_casing/ammo in storage.contents) + if(caliber != ammo.caliber) + continue + + load_ammo(ammo, user) + + if(loaded.len >= max_shells) + user << "[src] is full." + break + sleep(1 SECOND) + update_icon() //attempts to unload src. If allow_dump is set to 0, the speedloader unloading method will be disabled diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index ee46b5f42e..81149cf2cb 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -293,6 +293,7 @@ trajectory.increment() // increment the current location location = trajectory.return_location(location) // update the locally stored location data + update_light() //energy projectiles will look glowy and fun if(!location) qdel(src) // if it's left the world... kill it @@ -354,6 +355,7 @@ M.set_transform(T) M.pixel_x = location.pixel_x M.pixel_y = location.pixel_y + M.update_light() M.activate() /obj/item/projectile/proc/tracer_effect(var/matrix/M) @@ -364,6 +366,7 @@ P.set_transform(M) P.pixel_x = location.pixel_x P.pixel_y = location.pixel_y + P.update_light() if(!hitscan) P.activate(step_delay) //if not a hitscan projectile, remove after a single delay else @@ -377,6 +380,7 @@ P.set_transform(M) P.pixel_x = location.pixel_x P.pixel_y = location.pixel_y + P.update_light() P.activate() //"Tracing" projectile diff --git a/code/modules/projectiles/projectile/animate.dm b/code/modules/projectiles/projectile/animate.dm index 0f92729ad4..c09b98a32b 100644 --- a/code/modules/projectiles/projectile/animate.dm +++ b/code/modules/projectiles/projectile/animate.dm @@ -5,6 +5,9 @@ damage_type = BURN nodamage = 1 check_armour = "energy" + light_range = 2 + light_power = 0.5 + light_color = "#55AAFF" /obj/item/projectile/animate/Bump(var/atom/change) if((istype(change, /obj/item) || istype(change, /obj/structure)) && !is_type_in_list(change, protected_objects)) diff --git a/code/modules/projectiles/projectile/beams.dm b/code/modules/projectiles/projectile/beams.dm index 1049f5f70d..1f0dd03854 100644 --- a/code/modules/projectiles/projectile/beams.dm +++ b/code/modules/projectiles/projectile/beams.dm @@ -9,6 +9,9 @@ var/frequency = 1 hitscan = 1 invisibility = 101 //beam projectiles are invisible as they are rendered by the effect engine + light_range = 2 + light_power = 0.5 + light_color = "#FF0D00" muzzle_type = /obj/effect/projectile/laser/muzzle tracer_type = /obj/effect/projectile/laser/tracer @@ -28,6 +31,11 @@ icon_state = "laser" damage = 15 +/obj/item/projectile/beam/burstlaser + damage = 30 + armor_penetration = 10 + + /obj/item/projectile/beam/midlaser damage = 40 armor_penetration = 10 @@ -37,20 +45,25 @@ icon_state = "heavylaser" damage = 60 armor_penetration = 30 + light_range = 3 + light_power = 1 + light_color = "#FF0D00" muzzle_type = /obj/effect/projectile/laser_heavy/muzzle tracer_type = /obj/effect/projectile/laser_heavy/tracer impact_type = /obj/effect/projectile/laser_heavy/impact /obj/item/projectile/beam/heavylaser/cannon - damage = 90 - armor_penetration = 100 + damage = 80 + armor_penetration = 50 + light_color = "#FF0D00" /obj/item/projectile/beam/xray name = "xray beam" icon_state = "xray" damage = 25 armor_penetration = 50 + light_color = "#00CC33" muzzle_type = /obj/effect/projectile/xray/muzzle tracer_type = /obj/effect/projectile/xray/tracer @@ -61,6 +74,7 @@ icon_state = "u_laser" damage = 50 armor_penetration = 30 + light_color = "#0066FF" muzzle_type = /obj/effect/projectile/laser_pulse/muzzle tracer_type = /obj/effect/projectile/laser_pulse/tracer @@ -75,6 +89,7 @@ name = "emitter beam" icon_state = "emitter" damage = 0 // The actual damage is computed in /code/modules/power/singularity/emitter.dm + light_color = "#00CC33" muzzle_type = /obj/effect/projectile/emitter/muzzle tracer_type = /obj/effect/projectile/emitter/tracer @@ -88,6 +103,7 @@ no_attack_log = 1 damage_type = BURN check_armour = "laser" + light_color = "#0066FF" muzzle_type = /obj/effect/projectile/laser_blue/muzzle tracer_type = /obj/effect/projectile/laser_blue/tracer @@ -108,6 +124,7 @@ no_attack_log = 1 damage_type = BURN check_armour = "laser" + light_color = "#FF0D00" /obj/item/projectile/beam/lastertag/red/on_hit(var/atom/target, var/blocked = 0) if(istype(target, /mob/living/carbon/human)) @@ -123,6 +140,7 @@ damage = 0 damage_type = BURN check_armour = "laser" + light_color = "#00C6FF" muzzle_type = /obj/effect/projectile/laser_omni/muzzle tracer_type = /obj/effect/projectile/laser_omni/tracer @@ -140,6 +158,7 @@ icon_state = "xray" damage = 50 armor_penetration = 10 + light_color = "#00CC33" muzzle_type = /obj/effect/projectile/xray/muzzle tracer_type = /obj/effect/projectile/xray/tracer @@ -152,6 +171,7 @@ taser_effect = 1 agony = 40 damage_type = HALLOSS + light_color = "#FFFFFF" muzzle_type = /obj/effect/projectile/stun/muzzle tracer_type = /obj/effect/projectile/stun/tracer diff --git a/code/modules/projectiles/projectile/energy.dm b/code/modules/projectiles/projectile/energy.dm index 9a9fa74292..3eb848c733 100644 --- a/code/modules/projectiles/projectile/energy.dm +++ b/code/modules/projectiles/projectile/energy.dm @@ -25,14 +25,14 @@ for (var/mob/living/carbon/M in viewers(T, flash_range)) if(M.eyecheck() < 1) M.flash_eyes() - if(ishuman(M)) - var/mob/living/carbon/human/H = M - flash_strength *= H.species.flash_mod + if(ishuman(M)) + var/mob/living/carbon/human/H = M + flash_strength *= H.species.flash_mod - if(flash_strength > 0) - H.confused = max(H.confused, flash_strength + 5) - H.eye_blind = max(H.eye_blind, flash_strength) - H.eye_blurry = max(H.eye_blurry, flash_strength + 5) + if(flash_strength > 0) + H.confused = max(H.confused, flash_strength + 5) + H.eye_blind = max(H.eye_blind, flash_strength) + H.eye_blurry = max(H.eye_blurry, flash_strength + 5) //snap pop @@ -68,6 +68,9 @@ taser_effect = 1 agony = 40 damage_type = HALLOSS + light_range = 2 + light_power = 0.5 + light_color = "#FFFFFF" //Damage will be handled on the MOB side, to prevent window shattering. /obj/item/projectile/energy/electrode/strong @@ -85,6 +88,9 @@ nodamage = 1 damage_type = CLONE irradiate = 40 + light_range = 2 + light_power = 0.5 + light_color = "#33CC00" /obj/item/projectile/energy/dart @@ -124,3 +130,6 @@ damage = 20 damage_type = TOX irradiate = 20 + light_range = 2 + light_power = 0.5 + light_color = "#33CC00" diff --git a/code/modules/projectiles/projectile/special.dm b/code/modules/projectiles/projectile/special.dm index 788886af30..b567512a05 100644 --- a/code/modules/projectiles/projectile/special.dm +++ b/code/modules/projectiles/projectile/special.dm @@ -5,6 +5,9 @@ damage_type = BURN nodamage = 1 check_armour = "energy" + light_range = 2 + light_power = 0.5 + light_color = "#55AAFF" on_hit(var/atom/target, var/blocked = 0) @@ -32,6 +35,9 @@ nodamage = 1 check_armour = "energy" var/temperature = 300 + light_range = 2 + light_power = 0.5 + light_color = "#55AAFF" on_hit(var/atom/target, var/blocked = 0)//These two could likely check temp protection on the mob @@ -77,6 +83,9 @@ damage_type = TOX nodamage = 1 check_armour = "energy" + light_range = 2 + light_power = 0.5 + light_color = "#33CC00" on_hit(var/atom/target, var/blocked = 0) var/mob/living/M = target @@ -116,6 +125,9 @@ damage_type = TOX nodamage = 1 check_armour = "energy" + light_range = 2 + light_power = 0.5 + light_color = "#FFFFFF" on_hit(var/atom/target, var/blocked = 0) var/mob/M = target @@ -136,6 +148,7 @@ if(ishuman(target)) var/mob/living/carbon/human/M = target M.confused += rand(5,8) + /obj/item/projectile/chameleon name = "bullet" icon_state = "bullet" diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm index f051e8307f..fcabfa811c 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm @@ -125,10 +125,10 @@ /datum/reagent/water/touch_mob(var/mob/living/L, var/amount) if(istype(L)) - var/needed = L.fire_stacks * 10 + var/needed = L.fire_stacks * 5 if(amount > needed) L.ExtinguishMob() - L.adjust_fire_stacks(-(amount / 10)) + L.adjust_fire_stacks(-(amount / 5)) remove_self(needed) /datum/reagent/water/affect_touch(var/mob/living/carbon/M, var/alien, var/removed) diff --git a/code/modules/research/designs.dm b/code/modules/research/designs.dm index c0ecdbfc3d..78715938c3 100644 --- a/code/modules/research/designs.dm +++ b/code/modules/research/designs.dm @@ -1486,6 +1486,427 @@ CIRCUITS BELOW build_path = /obj/item/weapon/cartridge/captain sort_string = "VBAAO" + + +/datum/design/item/wirer + name = "Custom wirer tool" + id = "wirer" + req_tech = list(TECH_MATERIAL = 2, TECH_ENGINEERING = 2) + materials = list(DEFAULT_WALL_MATERIAL = 5000, "glass" = 2500) + build_path = /obj/item/device/integrated_electronics/wirer + sort_string = "VBVAA" + +/datum/design/item/debugger + name = "Custom circuit debugger tool" + id = "debugger" + req_tech = list(TECH_MATERIAL = 2, TECH_ENGINEERING = 2) + materials = list(DEFAULT_WALL_MATERIAL = 5000, "glass" = 2500) + build_path = /obj/item/device/integrated_electronics/debugger + sort_string = "VBVAB" + + + +/datum/design/item/custom_circuit_assembly + name = "Small custom assembly" + desc = "An customizable assembly for simple, small devices." + id = "assembly-small" + req_tech = list(TECH_MATERIAL = 3, TECH_ENGINEERING = 2, TECH_POWER = 2) + materials = list(DEFAULT_WALL_MATERIAL = 10000) + build_path = /obj/item/device/electronic_assembly + sort_string = "VCAAA" + +/datum/design/item/custom_circuit_assembly/medium + name = "Medium custom assembly" + desc = "An customizable assembly suited for more ambitious mechanisms." + id = "assembly-medium" + req_tech = list(TECH_MATERIAL = 4, TECH_ENGINEERING = 3, TECH_POWER = 3) + materials = list(DEFAULT_WALL_MATERIAL = 20000) + build_path = /obj/item/device/electronic_assembly/medium + +/datum/design/item/custom_circuit_assembly/large + name = "Large custom assembly" + desc = "An customizable assembly for large machines." + id = "assembly-large" + req_tech = list(TECH_MATERIAL = 5, TECH_ENGINEERING = 4, TECH_POWER = 4) + materials = list(DEFAULT_WALL_MATERIAL = 40000) + build_path = /obj/item/device/electronic_assembly/large + +/datum/design/circuit/integrated_circuit + req_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2) + +/datum/design/circuit/integrated_circuit/AssembleDesignName() + ..() + name = "Custom circuitry ([item_name])" + +/datum/design/circuit/integrated_circuit/AssembleDesignDesc() + if(!desc) + desc = "Allows for the construction of \a [name] custom circuit." + +/datum/design/circuit/integrated_circuit/arithmetic/AssembleDesignName() + ..() + name = "Custom circuitry \[Arithmetic\] ([item_name])" + +/datum/design/circuit/integrated_circuit/arithmetic/addition + id = "cc-addition" + build_path = /obj/item/integrated_circuit/arithmetic/addition + sort_string = "WAAAA" + +/datum/design/circuit/integrated_circuit/arithmetic/subtraction + id = "cc-subtraction" + build_path = /obj/item/integrated_circuit/arithmetic/subtraction + sort_string = "WAAAB" + +/datum/design/circuit/integrated_circuit/arithmetic/multiplication + id = "cc-multiplication" + build_path = /obj/item/integrated_circuit/arithmetic/multiplication + sort_string = "WAAAC" + +/datum/design/circuit/integrated_circuit/arithmetic/division + id = "cc-division" + build_path = /obj/item/integrated_circuit/arithmetic/division + sort_string = "WAAAD" + +/datum/design/circuit/integrated_circuit/arithmetic/absolute + id = "cc-absolute" + build_path = /obj/item/integrated_circuit/arithmetic/absolute + sort_string = "WAAAE" + +/datum/design/circuit/integrated_circuit/arithmetic/average + id = "cc-average" + build_path = /obj/item/integrated_circuit/arithmetic/average + sort_string = "WAAAF" + +/datum/design/circuit/integrated_circuit/arithmetic/pi + id = "cc-pi" + build_path = /obj/item/integrated_circuit/arithmetic/pi + sort_string = "WAAAG" + +/datum/design/circuit/integrated_circuit/arithmetic/random + id = "cc-random" + build_path = /obj/item/integrated_circuit/arithmetic/random + sort_string = "WAAAH" + + + +/datum/design/circuit/integrated_circuit/converter/AssembleDesignName() + ..() + name = "Custom circuitry \[Conversion\] ([item_name])" + +/datum/design/circuit/integrated_circuit/converter/num2text + id = "cc-num2text" + build_path = /obj/item/integrated_circuit/converter/num2text + sort_string = "WAABA" + +/datum/design/circuit/integrated_circuit/converter/text2num + id = "cc-text2num" + build_path = /obj/item/integrated_circuit/converter/text2num + sort_string = "WAABB" + +/datum/design/circuit/integrated_circuit/converter/ref2text + id = "cc-ref2text" + build_path = /obj/item/integrated_circuit/converter/ref2text + sort_string = "WAABC" + +/datum/design/circuit/integrated_circuit/converter/lowercase + id = "cc-lowercase" + build_path = /obj/item/integrated_circuit/converter/lowercase + sort_string = "WAABD" + +/datum/design/circuit/integrated_circuit/converter/uppercase + id = "cc-uppercase" + build_path = /obj/item/integrated_circuit/converter/uppercase + sort_string = "WAABD" + +/datum/design/circuit/integrated_circuit/converter/concatenatior + id = "cc-concatenatior" + build_path = /obj/item/integrated_circuit/converter/concatenatior + sort_string = "WAABC" + + + +/datum/design/circuit/integrated_circuit/coordinate/AssembleDesignName() + ..() + name = "Custom circuitry \[Coordinate\] ([item_name])" + +/datum/design/circuit/integrated_circuit/coordinate/gps + id = "cc-gps" + build_path = /obj/item/integrated_circuit/gps + sort_string = "WAACA" + +/datum/design/circuit/integrated_circuit/coordinate/abs_to_rel_coords + id = "cc-abs_to_rel_coords" + build_path = /obj/item/integrated_circuit/abs_to_rel_coords + sort_string = "WAACB" + + + +/datum/design/circuit/integrated_circuit/transfer/AssembleDesignName() + ..() + name = "Custom circuitry \[Transfer\] ([item_name])" + +/datum/design/circuit/integrated_circuit/transfer/splitter + id = "cc-splitter" + build_path = /obj/item/integrated_circuit/transfer/splitter + sort_string = "WAADA" + +/datum/design/circuit/integrated_circuit/transfer/splitter4 + id = "cc-splitter4" + build_path = /obj/item/integrated_circuit/transfer/splitter/medium + sort_string = "WAADB" + +/datum/design/circuit/integrated_circuit/transfer/splitter8 + id = "cc-splitter8" + build_path = /obj/item/integrated_circuit/transfer/splitter/large + sort_string = "WAADC" + +/datum/design/circuit/integrated_circuit/transfer/activator_splitter + id = "cc-activator_splitter" + build_path = /obj/item/integrated_circuit/transfer/activator_splitter + sort_string = "WAADD" + +/datum/design/circuit/integrated_circuit/transfer/activator_splitter4 + id = "cc-activator_splitter4" + build_path = /obj/item/integrated_circuit/transfer/activator_splitter/medium + sort_string = "WAADE" + +/datum/design/circuit/integrated_circuit/transfer/activator_splitter8 + id = "cc-activator_splitter8" + build_path = /obj/item/integrated_circuit/transfer/activator_splitter/large + sort_string = "WAADF" + + + +/datum/design/circuit/integrated_circuit/input_output/AssembleDesignName() + ..() + name = "Custom circuitry \[Input/Output\] ([item_name])" + +/datum/design/circuit/integrated_circuit/input_output/button + id = "cc-button" + build_path = /obj/item/integrated_circuit/input/button + sort_string = "WAAEA" + +/datum/design/circuit/integrated_circuit/input_output/numberpad + id = "cc-numberpad" + build_path = /obj/item/integrated_circuit/input/numberpad + sort_string = "WAAEB" + +/datum/design/circuit/integrated_circuit/input_output/textpad + id = "cc-textpad" + build_path = /obj/item/integrated_circuit/input/textpad + sort_string = "WAAEC" + +/datum/design/circuit/integrated_circuit/input_output/screen + id = "cc-screen" + build_path = /obj/item/integrated_circuit/output/screen + sort_string = "WAAED" + +/datum/design/circuit/integrated_circuit/input_output/med_scanner + id = "cc-medscanner" + build_path = /obj/item/integrated_circuit/input/med_scanner + req_tech = list(TECH_MATERIAL = 2, TECH_MAGNETS = 2, TECH_BIOMED = 2) + sort_string = "WAAEE" + +/datum/design/circuit/integrated_circuit/input_output/adv_med_scanner + id = "cc-advmedscanner" + build_path = /obj/item/integrated_circuit/input/adv_med_scanner + req_tech = list(TECH_MATERIAL = 2, TECH_MAGNETS = 3, TECH_BIOMED = 4) + sort_string = "WAAEF" + +/datum/design/circuit/integrated_circuit/input_output/local_locator + id = "cc-locallocator" + build_path = /obj/item/integrated_circuit/input/local_locator + sort_string = "WAAEG" + +/datum/design/circuit/integrated_circuit/input_output/signaler + id = "cc-signaler" + build_path = /obj/item/integrated_circuit/input/signaler + sort_string = "WAAEJ" + +/datum/design/circuit/integrated_circuit/input_output/light + id = "cc-light" + build_path = /obj/item/integrated_circuit/output/light + sort_string = "WAAEH" + +/datum/design/circuit/integrated_circuit/input_output/adv_light + id = "cc-adv_light" + build_path = /obj/item/integrated_circuit/output/light/advanced + sort_string = "WAAEI" + +/datum/design/circuit/integrated_circuit/input_output/beeper + id = "cc-sound_beeper" + build_path = /obj/item/integrated_circuit/output/sound/beeper + sort_string = "WAAEJ" + +/datum/design/circuit/integrated_circuit/input_output/beepsky_sound + id = "cc-sound_beepsky" + build_path = /obj/item/integrated_circuit/output/sound/beepsky + sort_string = "WAAEK" + req_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_ILLEGAL = 1) + +/datum/design/circuit/integrated_circuit/input_output/EPv2 + id = "cc-epv2" + build_path = /obj/item/integrated_circuit/input/EPv2 + sort_string = "WAAEL" + req_tech = list(TECH_ENGINEERING = 2, TECH_DATA = 2, TECH_MAGNETS = 2, TECH_BLUESPACE = 2) + + +/datum/design/circuit/integrated_circuit/logic/AssembleDesignName() + ..() + name = "Custom circuitry \[Logic\] ([item_name])" + +/datum/design/circuit/integrated_circuit/logic/equals + id = "cc-equals" + build_path = /obj/item/integrated_circuit/logic/equals + sort_string = "WAAFA" + +/datum/design/circuit/integrated_circuit/logic/not + id = "cc-not" + build_path = /obj/item/integrated_circuit/logic/not + sort_string = "WAAFB" + +/datum/design/circuit/integrated_circuit/logic/and + id = "cc-and" + build_path = /obj/item/integrated_circuit/logic/and + sort_string = "WAAFC" + +/datum/design/circuit/integrated_circuit/logic/or + id = "cc-or" + build_path = /obj/item/integrated_circuit/logic/or + sort_string = "WAAFD" + +/datum/design/circuit/integrated_circuit/logic/less_than + id = "cc-less_than" + build_path = /obj/item/integrated_circuit/logic/less_than + sort_string = "WAAFE" + +/datum/design/circuit/integrated_circuit/logic/less_than_or_equal + id = "cc-less_than_or_equal" + build_path = /obj/item/integrated_circuit/logic/less_than_or_equal + sort_string = "WAAFF" + +/datum/design/circuit/integrated_circuit/logic/greater_than + id = "cc-greater_than" + build_path = /obj/item/integrated_circuit/logic/greater_than + sort_string = "WAAFG" + +/datum/design/circuit/integrated_circuit/logic/greater_than_or_equal + id = "cc-greater_than_or_equal" + build_path = /obj/item/integrated_circuit/logic/greater_than_or_equal + sort_string = "WAAFH" + + + +/datum/design/circuit/integrated_circuit/manipulation/AssembleDesignName() + ..() + name = "Custom circuitry \[Manipulation\] ([item_name])" + +/datum/design/circuit/integrated_circuit/manipulation/weapon_firing + name = "weapon firing mechanism" + id = "cc-weapon_firing" + build_path = /obj/item/integrated_circuit/manipulation/weapon_firing + sort_string = "WAAGA" + req_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3, TECH_COMBAT = 4) + +/datum/design/circuit/integrated_circuit/manipulation/smoke + name = "smoke generator" + id = "cc-smoke" + build_path = /obj/item/integrated_circuit/manipulation/smoke + sort_string = "WAAGB" + req_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3, TECH_BIO = 4) + +/datum/design/circuit/integrated_circuit/manipulation/locomotion + name = "locomotion" + id = "cc-locomotion" + build_path = /obj/item/integrated_circuit/manipulation/locomotion + sort_string = "WAAGB" + req_tech = list(TECH_ENGINEERING = 3, TECH_DATA = 3) + + + +/datum/design/circuit/integrated_circuit/memory/AssembleDesignName() + ..() + name = "Custom circuitry \[Memory\] ([item_name])" + +/datum/design/circuit/integrated_circuit/memory + id = "cc-memory" + build_path = /obj/item/integrated_circuit/memory + sort_string = "WAAHA" + +/datum/design/circuit/integrated_circuit/memory/medium + id = "cc-memory4" + build_path = /obj/item/integrated_circuit/memory/medium + sort_string = "WAAHB" + +/datum/design/circuit/integrated_circuit/memory/large + id = "cc-memory8" + build_path = /obj/item/integrated_circuit/memory/large + sort_string = "WAAHC" + +/datum/design/circuit/integrated_circuit/memory/huge + id = "cc-memory16" + build_path = /obj/item/integrated_circuit/memory/huge + sort_string = "WAAHD" + +/datum/design/circuit/integrated_circuit/memory/constant + id = "cc-constant" + build_path = /obj/item/integrated_circuit/memory/constant + sort_string = "WAAHH" + +/datum/design/circuit/integrated_circuit/time/AssembleDesignName() + ..() + name = "Custom circuitry \[Time\] ([item_name])" + +/datum/design/circuit/integrated_circuit/time/delay + id = "cc-delay" + build_path = /obj/item/integrated_circuit/time/delay + sort_string = "WAAIA" + +/datum/design/circuit/integrated_circuit/time/delay/five_sec + id = "cc-five_sec_delay" + build_path = /obj/item/integrated_circuit/time/delay/five_sec + sort_string = "WAAIB" + +/datum/design/circuit/integrated_circuit/time/delay/one_sec + id = "cc-one_sec_delay" + build_path = /obj/item/integrated_circuit/time/delay/one_sec + sort_string = "WAAIC" + +/datum/design/circuit/integrated_circuit/time/delay/half_sec + id = "cc-half_sec_delay" + build_path = /obj/item/integrated_circuit/time/delay/half_sec + sort_string = "WAAID" + +/datum/design/circuit/integrated_circuit/time/delay/tenth_sec + id = "cc-tenth_sec_delay" + build_path = /obj/item/integrated_circuit/time/delay/tenth_sec + sort_string = "WAAIF" + +/datum/design/circuit/integrated_circuit/time/delay/custom + id = "cc-custom_delay" + build_path = /obj/item/integrated_circuit/time/delay/custom + sort_string = "WAAIG" + +/datum/design/circuit/integrated_circuit/time/ticker + id = "cc-ticker" + build_path = /obj/item/integrated_circuit/time/ticker + sort_string = "WAAIH" + +/datum/design/circuit/integrated_circuit/time/ticker/slow + id = "cc-ticker_slow" + build_path = /obj/item/integrated_circuit/time/ticker/slow + sort_string = "WAAII" + +/datum/design/circuit/integrated_circuit/time/ticker/fast + id = "cc-ticker_fast" + build_path = /obj/item/integrated_circuit/time/ticker/fast + sort_string = "WAAIJ" + req_tech = list(TECH_ENGINEERING = 4, TECH_DATA = 4) + +/datum/design/circuit/integrated_circuit/time/clock + id = "cc-clock" + build_path = /obj/item/integrated_circuit/time/clock + sort_string = "WAAIK" + /* Uncomment if someone makes these buildable /datum/design/circuit/general_alert name = "general alert console" diff --git a/code/modules/scripting/Implementations/Telecomms.dm b/code/modules/scripting/Implementations/Telecomms.dm index 87c6fa5ea3..1277d2b594 100644 --- a/code/modules/scripting/Implementations/Telecomms.dm +++ b/code/modules/scripting/Implementations/Telecomms.dm @@ -2,7 +2,7 @@ /* --- Traffic Control Scripting Language --- */ - // Nanotrasen TCS Language - Made by Doohl + // NanoTrasen TCS Language - Made by Doohl /n_Interpreter/TCS_Interpreter var/datum/TCS_Compiler/Compiler diff --git a/code/modules/shuttles/shuttle_ferry.dm b/code/modules/shuttles/shuttle_ferry.dm index 5d6663f3b5..0a288a1ba9 100644 --- a/code/modules/shuttles/shuttle_ferry.dm +++ b/code/modules/shuttles/shuttle_ferry.dm @@ -16,7 +16,7 @@ //TODO: change location to a string and use a mapping for area and dock targets. var/dock_target_station var/dock_target_offsite - + var/last_dock_attempt_time = 0 /datum/shuttle/ferry/short_jump(var/area/origin,var/area/destination) @@ -85,15 +85,15 @@ long_jump(interim=area_transition, travel_time=move_time, direction=transit_direction) else short_jump() - + process_state = WAIT_ARRIVE - + if (WAIT_ARRIVE) if (moving_status == SHUTTLE_IDLE) dock() in_use = null //release lock process_state = WAIT_FINISH - + if (WAIT_FINISH) if (skip_docking_checks() || docking_controller.docked() || world.time > last_dock_attempt_time + DOCK_ATTEMPT_TIMEOUT) process_state = IDLE_STATE diff --git a/code/modules/surgery/bones.dm b/code/modules/surgery/bones.dm index cc4428fcb6..818e208ff4 100644 --- a/code/modules/surgery/bones.dm +++ b/code/modules/surgery/bones.dm @@ -140,7 +140,6 @@ user.visible_message("\blue [user] has mended the damaged bones in [target]'s [affected.name] with \the [tool]." , \ "\blue You have mended the damaged bones in [target]'s [affected.name] with \the [tool]." ) affected.status &= ~ORGAN_BROKEN - affected.status &= ~ORGAN_SPLINTED affected.stage = 0 fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) diff --git a/code/modules/vehicles/vehicle.dm b/code/modules/vehicles/vehicle.dm index ddc56dad3f..80eb2f1a44 100644 --- a/code/modules/vehicles/vehicle.dm +++ b/code/modules/vehicles/vehicle.dm @@ -93,6 +93,7 @@ if(health < maxhealth) if(open) health = min(maxhealth, health+10) + user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) user.visible_message("\red [user] repairs [src]!","\blue You repair [src]!") else user << "Unable to repair with the maintenance panel closed." @@ -101,6 +102,7 @@ else user << "Unable to repair while [src] is off." else if(hasvar(W,"force") && hasvar(W,"damtype")) + user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) switch(W.damtype) if("fire") health -= W.force * fire_dam_coeff diff --git a/code/modules/ventcrawl/ventcrawl.dm b/code/modules/ventcrawl/ventcrawl.dm new file mode 100644 index 0000000000..9b2b83d3e7 --- /dev/null +++ b/code/modules/ventcrawl/ventcrawl.dm @@ -0,0 +1,185 @@ +var/list/ventcrawl_machinery = list( + /obj/machinery/atmospherics/unary/vent_pump, + /obj/machinery/atmospherics/unary/vent_scrubber + ) + +// Vent crawling whitelisted items, whoo +/mob/living/var/list/can_enter_vent_with = list( + /obj/item/weapon/implant, + /obj/item/device/radio/borg, + /obj/item/weapon/holder, + /obj/machinery/camera, + /mob/living/simple_animal/borer, + ) + +/mob/living/var/list/icon/pipes_shown = list() +/mob/living/var/last_played_vent +/mob/living/var/is_ventcrawling = 0 +/mob/var/next_play_vent = 0 + +/mob/living/proc/can_ventcrawl() + if(!client) + return FALSE + if(!(/mob/living/proc/ventcrawl in verbs)) + to_chat(src, "You don't possess the ability to ventcrawl!") + return FALSE + if(incapacitated()) + to_chat(src, "You cannot ventcrawl in your current state!") + return FALSE + return ventcrawl_carry() + +/mob/living/Login() + . = ..() + //login during ventcrawl + if(is_ventcrawling && istype(loc, /obj/machinery/atmospherics)) //attach us back into the pipes + remove_ventcrawl() + add_ventcrawl(loc) + +/mob/living/carbon/slime/can_ventcrawl() + if(Victim) + to_chat(src, "You cannot ventcrawl while feeding.") + return FALSE + . = ..() + +/mob/living/proc/is_allowed_vent_crawl_item(var/obj/item/carried_item) + if(carried_item == ability_master) + return 1 + for(var/type in can_enter_vent_with) + if(istype(carried_item, can_enter_vent_with)) + return get_inventory_slot(carried_item) == 0 + return 0 + +/mob/living/carbon/is_allowed_vent_crawl_item(var/obj/item/carried_item) + if(carried_item in internal_organs) + return 1 + return ..() + +/mob/living/carbon/human/is_allowed_vent_crawl_item(var/obj/item/carried_item) + if(carried_item in organs) + return 1 + return ..() + +/mob/living/simple_animal/spiderbot/is_allowed_vent_crawl_item(var/obj/item/carried_item) + if(carried_item == held_item) + return 1 + return ..() + +/mob/living/proc/ventcrawl_carry() + for(var/atom/A in contents) + if(!is_allowed_vent_crawl_item(A)) + to_chat(src, "You can't carry \the [A] while ventcrawling!") + return FALSE + return TRUE + +/mob/living/AltClickOn(var/atom/A) + if(is_type_in_list(A,ventcrawl_machinery)) + handle_ventcrawl(A) + return 1 + return ..() + +/mob/proc/start_ventcrawl() + var/atom/pipe + var/list/pipes = list() + for(var/obj/machinery/atmospherics/unary/U in range(1)) + if(is_type_in_list(U,ventcrawl_machinery) && Adjacent(U)) + pipes |= U + if(!pipes || !pipes.len) + to_chat(src, "There are no pipes that you can ventcrawl into within range!") + return + if(pipes.len == 1) + pipe = pipes[1] + else + pipe = input("Crawl Through Vent", "Pick a pipe") as null|anything in pipes + if(canmove && pipe) + return pipe + +/mob/living/carbon/alien/ventcrawl_carry() + return 1 + +/mob/living/var/ventcrawl_layer = 3 + +/mob/living/proc/handle_ventcrawl(var/atom/clicked_on) + if(!can_ventcrawl()) + return + + var/obj/machinery/atmospherics/unary/vent_found + if(clicked_on && Adjacent(clicked_on)) + vent_found = clicked_on + if(!istype(vent_found) || !vent_found.can_crawl_through()) + vent_found = null + + if(!vent_found) + for(var/obj/machinery/atmospherics/machine in range(1,src)) + if(is_type_in_list(machine, ventcrawl_machinery)) + vent_found = machine + + if(!vent_found || !vent_found.can_crawl_through()) + vent_found = null + + if(vent_found) + break + + if(vent_found) + if(vent_found.network && (vent_found.network.normal_members.len || vent_found.network.line_members.len)) + + to_chat(src, "You begin climbing into the ventilation system...") + if(vent_found.air_contents && !issilicon(src)) + + switch(vent_found.air_contents.temperature) + if(0 to BODYTEMP_COLD_DAMAGE_LIMIT) + to_chat(src, "You feel a painful freeze coming from the vent!") + if(BODYTEMP_COLD_DAMAGE_LIMIT to T0C) + to_chat(src, "You feel an icy chill coming from the vent.") + if(T0C + 40 to BODYTEMP_HEAT_DAMAGE_LIMIT) + to_chat(src, "You feel a hot wash coming from the vent.") + if(BODYTEMP_HEAT_DAMAGE_LIMIT to INFINITY) + to_chat(src, "You feel a searing heat coming from the vent!") + + switch(vent_found.air_contents.return_pressure()) + if(0 to HAZARD_LOW_PRESSURE) + to_chat(src, "You feel a rushing draw pulling you into the vent!") + if(HAZARD_LOW_PRESSURE to WARNING_LOW_PRESSURE) + to_chat(src, "You feel a strong drag pulling you into the vent.") + if(WARNING_HIGH_PRESSURE to HAZARD_HIGH_PRESSURE) + to_chat(src, "You feel a strong current pushing you away from the vent.") + if(HAZARD_HIGH_PRESSURE to INFINITY) + to_chat(src, "You feel a roaring wind pushing you away from the vent!") + + if(!do_after(src, 45, vent_found, 1, 1)) + return + if(!can_ventcrawl()) + return + + visible_message("[src] scrambles into the ventilation ducts!", "You climb into the ventilation system.") + + forceMove(vent_found) + add_ventcrawl(vent_found) + + else + to_chat(src, "This vent is not connected to anything.") + + else + to_chat(src, "You must be standing on or beside an air vent to enter it.") + +/mob/living/proc/add_ventcrawl(obj/machinery/atmospherics/starting_machine) + is_ventcrawling = 1 + //candrop = 0 + var/datum/pipe_network/network = starting_machine.return_network(starting_machine) + if(!network) + return + for(var/datum/pipeline/pipeline in network.line_members) + for(var/obj/machinery/atmospherics/A in (pipeline.members || pipeline.edges)) + if(!A.pipe_image) + A.pipe_image = image(A, A.loc, layer = 20, dir = A.dir) + pipes_shown += A.pipe_image + client.images += A.pipe_image + +/mob/living/proc/remove_ventcrawl() + is_ventcrawling = 0 + //candrop = 1 + if(client) + for(var/image/current_image in pipes_shown) + client.images -= current_image + client.eye = src + + pipes_shown.len = 0 \ No newline at end of file diff --git a/code/modules/ventcrawl/ventcrawl_atmospherics.dm b/code/modules/ventcrawl/ventcrawl_atmospherics.dm new file mode 100644 index 0000000000..bb2d121125 --- /dev/null +++ b/code/modules/ventcrawl/ventcrawl_atmospherics.dm @@ -0,0 +1,86 @@ +/obj/machinery/atmospherics/var/image/pipe_image + +/obj/machinery/atmospherics/Destroy() + for(var/mob/living/M in src) //ventcrawling is serious business + M.remove_ventcrawl() + M.forceMove(get_turf(src)) + if(pipe_image) + for(var/mob/living/M in player_list) + if(M.client) + M.client.images -= pipe_image + M.pipes_shown -= pipe_image + pipe_image = null + . = ..() + +/obj/machinery/atmospherics/ex_act(severity) + for(var/atom/movable/A in src) //ventcrawling is serious business + A.ex_act(severity) + . = ..() + +/obj/machinery/atmospherics/Entered(atom/movable/Obj) + if(istype(Obj, /mob/living)) + var/mob/living/L = Obj + L.ventcrawl_layer = layer + . = ..() + +/obj/machinery/atmospherics/relaymove(mob/living/user, direction) + if(user.loc != src || !(direction & initialize_directions)) //can't go in a way we aren't connecting to + return + ventcrawl_to(user,findConnecting(direction, user.ventcrawl_layer),direction) + +/obj/machinery/atmospherics/proc/ventcrawl_to(var/mob/living/user, var/obj/machinery/atmospherics/target_move, var/direction) + if(target_move) + if(is_type_in_list(target_move, ventcrawl_machinery) && target_move.can_crawl_through()) + user.remove_ventcrawl() + user.forceMove(target_move.loc) //handles entering and so on + user.visible_message("You hear something squeezing through the ducts.", "You climb out the ventilation system.") + else if(target_move.can_crawl_through()) + if(target_move.return_network(target_move) != return_network(src)) + user.remove_ventcrawl() + user.add_ventcrawl(target_move) + user.forceMove(target_move) + user.client.eye = target_move //if we don't do this, Byond only updates the eye every tick - required for smooth movement + if(world.time > user.next_play_vent) + user.next_play_vent = world.time+30 + playsound(src, 'sound/machines/ventcrawl.ogg', 50, 1, -3) + else + if((direction & initialize_directions) || is_type_in_list(src, ventcrawl_machinery) && src.can_crawl_through()) //if we move in a way the pipe can connect, but doesn't - or we're in a vent + user.remove_ventcrawl() + user.forceMove(src.loc) + user.visible_message("You hear something squeezing through the pipes.", "You climb out the ventilation system.") + user.canmove = 0 + spawn(1) + user.canmove = 1 + +/obj/machinery/atmospherics/proc/can_crawl_through() + return 1 + +/obj/machinery/atmospherics/proc/findConnecting(var/direction) + for(var/obj/machinery/atmospherics/target in get_step(src,direction)) + if(target.initialize_directions & get_dir(target,src)) + if(isConnectable(target) && target.isConnectable(src)) + return target + +/obj/machinery/atmospherics/proc/isConnectable(var/obj/machinery/atmospherics/target) + return (target == node1 || target == node2) + +/obj/machinery/atmospherics/pipe/manifold/isConnectable(var/obj/machinery/atmospherics/target) + return (target == node3 || ..()) + +obj/machinery/atmospherics/trinary/isConnectable(var/obj/machinery/atmospherics/target) + return (target == node3 || ..()) + +/obj/machinery/atmospherics/pipe/manifold4w/isConnectable(var/obj/machinery/atmospherics/target) + return (target == node3 || target == node4 || ..()) + +/obj/machinery/atmospherics/tvalve/isConnectable(var/obj/machinery/atmospherics/target) + return (target == node3 || ..()) + +/obj/machinery/atmospherics/pipe/cap/isConnectable(var/obj/machinery/atmospherics/target) + return (target == node || ..()) + +/obj/machinery/atmospherics/portables_connector/isConnectable(var/obj/machinery/atmospherics/target) + return (target == node || ..()) + +/obj/machinery/atmospherics/unary/isConnectable(var/obj/machinery/atmospherics/target) + return (target == node || ..()) diff --git a/code/modules/ventcrawl/ventcrawl_multiz.dm b/code/modules/ventcrawl/ventcrawl_multiz.dm new file mode 100644 index 0000000000..87ef8f9ba7 --- /dev/null +++ b/code/modules/ventcrawl/ventcrawl_multiz.dm @@ -0,0 +1,24 @@ +/obj/machinery/atmospherics/pipe/zpipe/up/verb/ventcrawl_move_up() + set name = "Ventcrawl Upwards" + set desc = "Climb up through a pipe." + set category = "Abilities" + set src = usr.loc + var/obj/machinery/atmospherics/target = check_ventcrawl(GetAbove(loc)) + if(target) ventcrawl_to(usr, target, UP) + +/obj/machinery/atmospherics/pipe/zpipe/down/verb/ventcrawl_move_down() + set name = "Ventcrawl Downwards" + set desc = "Climb down through a pipe." + set category = "Abilities" + set src = usr.loc + var/obj/machinery/atmospherics/target = check_ventcrawl(GetBelow(loc)) + if(target) ventcrawl_to(usr, target, DOWN) + +/obj/machinery/atmospherics/pipe/zpipe/proc/check_ventcrawl(var/turf/target) + if(!istype(target)) + return + if(node1 in target) + return node1 + if(node2 in target) + return node2 + return \ No newline at end of file diff --git a/code/modules/ventcrawl/ventcrawl_verb.dm b/code/modules/ventcrawl/ventcrawl_verb.dm new file mode 100644 index 0000000000..b49f22836d --- /dev/null +++ b/code/modules/ventcrawl/ventcrawl_verb.dm @@ -0,0 +1,7 @@ +/mob/living/proc/ventcrawl() + set name = "Crawl through Vent" + set desc = "Enter an air vent and crawl through the pipe system." + set category = "Abilities" + var/pipe = start_ventcrawl() + if(pipe) + handle_ventcrawl() diff --git a/code/unit_tests/zas_tests.dm b/code/unit_tests/zas_tests.dm index a28abaa881..cbf26f061f 100644 --- a/code/unit_tests/zas_tests.dm +++ b/code/unit_tests/zas_tests.dm @@ -44,7 +44,7 @@ return test_result if(expectation == UT_NORMAL) - + if(abs(temp - T20C) > 10) test_result["msg"] = "Temperature out of bounds: [temp] | [t_msg]" return test_result @@ -78,7 +78,7 @@ return 1 /datum/unit_test/zas_area_test/supply_centcomm - name = "ZAS: Supply Shuttle (CentComm)" + name = "ZAS: Supply Shuttle (CentCom)" area_path = /area/supply/dock /datum/unit_test/zas_area_test/emergency_shuttle @@ -95,7 +95,7 @@ /datum/unit_test/zas_area_test/cargo_maint name = "ZAS: Cargo Maintenance" - area_path = /area/maintenance/cargo + area_path = /area/maintenance/cargo /datum/unit_test/zas_area_test/eng_shuttle name = "ZAS: Construction Site Shuttle (Station)" diff --git a/html/changelog.html b/html/changelog.html index fd4010ec16..fda0a46275 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -53,6 +53,50 @@ -->
+

19 September 2016

+

Anewbe updated:

+ +

MagmaRam updated:

+ +

Zuhayr updated:

+ + +

16 September 2016

+

Anewbe updated:

+ +

Chinsky updated:

+ +

Yoshax updated:

+ +

03 September 2016

Yosh updated: